diff options
196 files changed, 3215 insertions, 2217 deletions
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 85b27365d6e..a2b5ccf4ee9 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -1207,7 +1207,7 @@ get_package_version_DEB() { } check_package_DEB() { - r=`apt-cache policy $1 | grep -c 'Candidate:'` + r=`apt-cache show $1 | grep -c 'Package:'` if [ $r -ge 1 ]; then return 0 @@ -1298,15 +1298,35 @@ install_DEB() { THEORA_USE=true # Install newest libtiff-dev in debian/ubuntu. - TIFF="libtiff5" + TIFF="libtiff" check_package_DEB $TIFF if [ $? -eq 0 ]; then _packages="$_packages $TIFF-dev" else - TIFF="libtiff" + TIFF="libtiff5" check_package_DEB $TIFF if [ $? -eq 0 ]; then _packages="$_packages $TIFF-dev" + else + TIFF="libtiff4" # Some old distro, like e.g. ubuntu 10.04 :/ + check_package_DEB $TIFF + if [ $? -eq 0 ]; then + _packages="$_packages $TIFF-dev" + fi + fi + fi + + GIT="git" + check_package_DEB $GIT + if [ $? -eq 0 ]; then + INFO $GIT + _packages="$_packages $GIT" + else + GIT="git-core" # Some old distro, like e.g. ubuntu 10.04 :/ + check_package_DEB $GIT + if [ $? -eq 0 ]; then + INFO $GIT + _packages="$_packages $GIT" fi fi @@ -1471,7 +1491,7 @@ install_DEB() { else if $have_llvm; then INFO "" - install_packages_DEB flex bison libtbb-dev git + install_packages_DEB flex bison libtbb-dev # No package currently! INFO "" compile_OSL @@ -1484,7 +1504,7 @@ install_DEB() { INFO "WARNING! Skipping OpenCOLLADA installation, as requested..." else INFO "" - install_packages_DEB git libpcre3-dev libxml2-dev + install_packages_DEB libpcre3-dev libxml2-dev # Find path to libxml shared lib... _XML2_LIB=`dpkg -L libxml2-dev | grep -e ".*/libxml2.so"` # No package diff --git a/doc/python_api/rst/bge.render.rst b/doc/python_api/rst/bge.render.rst index d07d7a8734f..e203826d318 100644 --- a/doc/python_api/rst/bge.render.rst +++ b/doc/python_api/rst/bge.render.rst @@ -97,7 +97,7 @@ Functions The standalone player saves .png files. It does not support color space conversion or gamma correction. - When run from Blender, makeScreenshot supports Iris, IrisZ, TGA, Raw TGA, PNG, HamX, and Jpeg. + When run from Blender, makeScreenshot supports all Blender image file formats like PNG, TGA, Jpeg and OpenEXR. Gamma, Colorspace conversion and Jpeg compression are taken from the Render settings panels. :type filename: string diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt index a4910d94a37..025481f9954 100644 --- a/extern/libmv/CMakeLists.txt +++ b/extern/libmv/CMakeLists.txt @@ -45,12 +45,12 @@ set(SRC libmv/multiview/euclidean_resection.cc libmv/multiview/fundamental.cc libmv/multiview/homography.cc + libmv/multiview/panography.cc libmv/multiview/projection.cc libmv/multiview/triangulation.cc libmv/numeric/numeric.cc libmv/numeric/poly.cc libmv/simple_pipeline/bundle.cc - libmv/simple_pipeline/callbacks.cc libmv/simple_pipeline/camera_intrinsics.cc libmv/simple_pipeline/detect.cc libmv/simple_pipeline/initialize_reconstruction.cc diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog index a4f25f83a1c..a3d39d46f65 100644 --- a/extern/libmv/ChangeLog +++ b/extern/libmv/ChangeLog @@ -1,3 +1,169 @@ +commit e3b2bccba6145290738a6677c14f7369ec7a38cd +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Thu Apr 4 02:59:58 2013 +0600 + + Suppress strict compiler warnings in glags/glog libraries + +commit 5fca459adcf0a3419fa9cd8d983dc2c952d02647 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Thu Apr 4 01:20:18 2013 +0600 + + Lint cleanup, mostly white space and line width. + + Also moved own includes to the top of files. + + Should be no functional changes :) + +commit 9a9dd458a622928b91dbd3c79900577923283838 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Fri Mar 29 00:20:29 2013 +0600 + + Fix for TransformTracks in uncalibrated pipeline + + Transformation matrix was completely ignored by + TransformTracks() and final marker coordinate + exactly matched it's source coordinates. + + Seems to be just a typo in vector usage: need to + use "b" (which is transformed one) instead of "a" + when converting projective coordinate to 2D space. + +commit d35766cc9901609e32f4d80faba715695bea3c40 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Fri Mar 29 00:19:11 2013 +0600 + + Revert part of e2eb58c4230f94ef0c72fb4005e5434088d52e80 + + That commit included one change which shall have been + go as separate commit with more detailed description. + +commit e8d71b4e96fd78eb60773b6557d66da672e65753 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Mar 27 20:37:05 2013 +0600 + + Silenced more warnings + + - Added includes of own header to fast implementation files. + + - Camera intrinsics wouldn't complain about unknown pragma when + building without OpenMP support. + + TODO: Make it a CMake option to build libmv with OpenMP support. + Currently multi-threaded intrinsics only available when + using custom CMake rules for bundled libmv version + (as it's done in Blender). + +commit ad442812654f270dc088394410fda1b81b8dc450 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Mar 27 20:18:51 2013 +0600 + + Multithreaded camera intrinsics + + Implemented multithreaded buffer (un)distortion + for camera intrinsics using OpenMP. + + By default, (un)distortion is single-threaded, + but it is possible to as CameraIntrinsics to + use more threads by calling SetThreads method. + +commit c88b4881096174a16a9f9e6fc2c9dcad3e255b25 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Mar 27 18:45:09 2013 +0600 + + Movie functions implementation from panography header + into own CC implementation file. + + Before this all panography functions were declared as + static, which is not so much useful from re-useability + point of view. + +commit 2d2faf9104bc035722cff6775e1b8e7c93143aba +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Mar 27 18:37:36 2013 +0600 + + Build shared Ceres library only if BUILD_SHARED_LIBS is enabled + +commit daa3ddd3260ccaf2bf9c72eadb89213d91e549ec +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Mar 27 18:21:52 2013 +0600 + + Update Ceres to upstream version 1.5.0 + +commit cf5dc678878345ea3f221ce50cb2b9e539c2ab38 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Wed Mar 27 15:06:24 2013 +0600 + + Code cleanup: removed more deprecated FFmpeg API usage + + This time in qt-tracker application. + +commit e2eb58c4230f94ef0c72fb4005e5434088d52e80 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue Mar 26 17:19:51 2013 +0600 + + Code cleanup: silent unused variables warnings + +commit af89bb24667e39b7e655173ea807fdcfbeef4422 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue Mar 26 16:54:14 2013 +0600 + + Code cleanup: no need to declare empty body for ProgressUpdateCallback:invoke + + Make force this method to be overridden by derivative classes. + Also removed currently unneeded callbacks.cc. + +commit 0441d4ee06fad0219256a5704f931eec916a3868 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue Mar 26 16:37:27 2013 +0600 + + Code cleanup: silent type narrowing in qt-tracker + +commit cd4b61c976448d0fdedefb3ed4b21d70e078f94b +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue Mar 26 16:26:39 2013 +0600 + + Changes to unit testing + + - Move ceres test binaries to ${LIBMV_TESTS_OUTPUT_DIR}/ceres, + so they don't mess with libmv's application binaries and + tests. + + - Removed ceres_ prefix from ceres unit tests, only use this + prefix for targets (targets need to be unique name). + + - Added unit tests data for ceres, otherwise system_test fails. + + - Restored "test" makefile target. + +commit cf704ada08acc8b26167e7bfb3e1e88fd278de23 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue Mar 26 15:01:15 2013 +0600 + + Code cleanup: use rw-rw-r-- mode for source files + +commit 64b31e3e43acb52aaf6f591b9d1c2449bf6ef3bd +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue Mar 26 14:57:46 2013 +0600 + + Code cleanup: don't use deprecated FFmpeg API functions + +commit 2a3676499548ad5dba5a5c5eadf3bb71e640b612 +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue Mar 5 17:40:52 2013 +0600 + + Switch from DENSE_NORMAL_CHOLESKY to DENSE_QR + + DENSE_QR is better behaved numerically and after recent + changes from Sameer there's no big difference in speed. + +commit bcb920df02133da5b7e55fbc74edb9222004eecc +Author: Sergey Sharybin <sergey.vfx@gmail.com> +Date: Tue Mar 5 17:15:43 2013 +0600 + + Update Ceres to 1.5RC3 + + It brings optimization of DENSE_QR and DENSE_SCHUR solvers. + commit 473996468a4e67e7c860169181a4ff31ce9b8c80 Author: Sergey Sharybin <sergey.vfx@gmail.com> Date: Fri Mar 1 17:44:54 2013 +0600 @@ -533,268 +699,3 @@ Date: Fri Jun 8 17:42:17 2012 +0000 aborts immediately. The workaround for now is to disable the correlation checking, and examine your tracks carefully. A fix will get added shortly. - -commit 81d028f13738ebe2304287dfce90e91bc782e2cf -Author: Keir Mierle <mierle@gmail.com> -Date: Fri May 18 20:04:43 2012 +0000 - - Remove an unnecessary template<> line in libmv. Convert debug logs to LG. - -commit 238aaba241ef99995d254aadc974db719da04b96 -Author: Keir Mierle <mierle@gmail.com> -Date: Fri May 18 12:05:10 2012 +0000 - - Support normalization in the tracking prepass - - The last tracker commit added normalized tracking. This makes - tracking patches undergoing uniform illumination change easier. - However, the prepass which computes a quick translation-only - estimate of the warp did not take this into account. This commit - fixes that. - - This works reasonably well but in some examples the brute - initialization fails. I suspect this is due to the warped template - estimate in the current frame being too different from the - original, so there are multiple peaks in the normalized-SAD - correlation function. - - The solution is to use the previous frame for the brute - initialization and the keyframe for refinement, but that requires - architecture changes. - -commit 981ca4f6a679cd9ac3d086eae3cd946ce72ca8a5 -Author: Keir Mierle <mierle@gmail.com> -Date: Fri May 18 02:12:47 2012 +0000 - - Add light-normalized tracking to the planar tracker - - This commit adds the ability to normalize patterns by their - average value while tracking, to make them invariant to global - illumination changes. - - To see this in action, check out the "Lobby" scene from Hollywood - VFX. If you track the markers that are shadowed by the actress, - previously they would not track. With the scale adaption on, the - tracker would shrink the area to compensate for the changed - illumination, losing the track. With "Normalize" turned on, the - patch is correctly tracked and scale is maintained. - - A remaining problem is that only the Ceres cost function is - updated to handle the normalization. The brute translation search - does not take this into account. Perhaps "Prepass" (see below) - should get disabled if normalization is enabled until I fix the - prepass to normalize as well. - - There are a few other changes: - - - Bail out of the sampling loop early if the mask is zero; this - saves expensive samples of the image derivatives. - - - Fix a bug where the mask was ignored when sampling in the cost - functor. - -commit e9384b15fb2a6a5b81346d5758fa136f0911e945 -Author: Keir Mierle <mierle@gmail.com> -Date: Thu May 17 23:53:32 2012 +0000 - - Implement support for affine tracking in the planar tracker; cleanups. - -commit 021d41eed8b4ce6a4e37786ccd357ed5dc83a13f -Author: Keir Mierle <mierle@gmail.com> -Date: Thu May 17 21:26:06 2012 +0000 - - For the planar tracker, initialize the warp from the four correspondences - after brute force translation search. - -commit 003d1bf6145cfd30938b35f6e10d43708dbf916c -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Thu Dec 6 16:56:01 2012 +0600 - - Correction to region tracker options initialization. - - Based on patch from Keir to Blender: - https://svn.blender.org/svnroot/bf-blender/branches/soc-2011-tomato@46743 - -commit 6af47b218cfdf5219f0ebb3cb95459817cf9abf2 -Author: Keir Mierle <mierle@gmail.com> -Date: Thu May 17 02:31:52 2012 +0000 - - Add new planar tracker features and use the new planar API - - This commit removes the use of the legacy RegionTracker API from - Blender, and replaces it with the new TrackRegion API. This also - adds several features to the planar tracker in libmv: - - - Do a brute-force initialization of tracking similar to "Hybrid" - mode in the stable release, but using all floats. This is slower - but more accurate. It is still necessary to evaluate if the - performance loss is worth it. In particular, this change is - necessary to support high bit depth imagery. - - - Add support for masks over the search window. This is a step - towards supporting user-defined tracker masks. The tracker masks - will make it easy for users to make a mask for e.g. a ball. - - - Add Pearson product moment correlation coefficient checking (aka - "Correlation" in the UI. This causes tracking failure if the - tracked patch is not linearly related to the template. - - - Add support for warping a few points in addition to the supplied - points. This is useful because the tracking code deliberately - does not expose the underlying warp representation. Instead, - warps are specified in an aparametric way via the correspondences. - - - Remove the "num_samples_xy" concept and replace it with - automatic determination of the number of samples. This makes the - API easier for users. - - - Fix various bugs in the parameterizations. - - There remains a bug with subpixel precision tracking when in - "keyframe" mode; this will get fixed shortly. - -commit 16a46db104468cec80bd31ca9d5f8bffbe3e003e -Author: Keir Mierle <mierle@gmail.com> -Date: Mon May 14 12:15:38 2012 +0000 - - "Efficient Second-order Minimization" for the planar tracker - - This implements the "Efficient Second-order Minimization" - scheme, as supported by the existing translation tracker. - This increases the amount of per-iteration work, but - decreases the number of iterations required to converge and - also increases the size of the basin of attraction for the - optimization. - -commit 23243b1b1f3e1ab3ef862b47bca06ee876ac2cf4 -Author: Keir Mierle <mierle@gmail.com> -Date: Sun May 13 23:08:56 2012 +0000 - - Add a planar tracking implementation to libmv - - This adds a new planar tracking implementation to libmv. The - tracker is based on Ceres[1], the new nonlinear minimizer that - myself and Sameer released from Google as open source. Since - the motion model is more involved, the interface is - different than the RegionTracker interface used previously - in Blender. - - The ESM tracker, also known as the KLT tracker in the UI, is - temporarily changed to use the new Ceres-based planar - tracker in translation-only mode. Currently it is a bit - slower than ESM and also doesn't have all the bells and - whistles implemented. Those will come soon. Longer term, - both trackers will remain since Ceres is unlikely to be as - fast as ESM for pure translation solving, due to its - generality. - - The next step is to implement a new tracking UI. The current - UI assumes a translational motion model; the new one must - support arbitrary perspective transforms of the pattern - regions. - - [1] http://code.google.com/p/ceres-solver - -commit 52be92b53eb4decb1a316690b162196f227cc441 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Thu Dec 6 16:06:08 2012 +0600 - - Initial Ceres integration - - Currently only put sources to src/third_party/ceres and made sure they're - not giving compilation issues. - - Used Ceres upstream version 1.3.0. - - Needed to make some modifications to it's CMakeLists.txt also to glog and - fglags. They're described in README.libmv of this libraries. - - Basically: - - - Added -fPIC to glog/gflags, so shared ceres library could be linked - statically against this libraries. - - - Tweaked Ceres's build rules to use needed libraries from libmv's - third_party folder. - -commit b13f9d13122e091cb85855c2094386ccdef6e5a4 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed Dec 5 19:05:34 2012 +0600 - - Update Eigen to version 3.1.2 - - Mainly because of lots of warnings generating by gcc-4.7 which are - resolved in newer eigen version. - -commit 1f0dd94e8e37d3fe2df89282ec16a6a685fdde0b -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Fri May 25 16:36:44 2012 +0600 - - - Added avutil to qt-tracker linking when building with FFmpeg support. - On some platforms it seems to be required - - Synchronized QT Creator project for qt-tracker with changes in sources, - so no it might be compiled from QT Creator. - -commit b813dbe3f46bbbc7e73ac791d4665622e4fc7ba5 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed May 9 19:01:10 2012 +0600 - - Modal solver: Detect rigid transformation between initial frame and current - instead of detecting it between two neighbour frames. - - This prevents accumulation of error and seems to be working better in footages i've tested. - -commit 9254621c76daaf239ec1f535e197ca792eea97b6 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Wed May 9 18:57:00 2012 +0600 - - Backport changes made by Keir in Blender: - - - Enhance logging in libmv's trackers. - - Cleanups in brute_region_tracker.cc. - -commit d9c56b9d3c63f886d83129ca0ebed1e76d9c93d7 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Fri Apr 27 16:20:41 2012 +0600 - - Fixes for MinGW64 support by Caleb Joseph with slight modifications by Antony Riakiotakis - - - Functions snprintf and sincos shouldn't be redefined for MinGW64 - - Type pid_t shouldn't be re-defined for MinGW64 - -commit e1902b6938676011607ac99986b8b140bdbf090e -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Fri Apr 27 16:04:19 2012 +0600 - - Fixes for Qt calibration tool - - - Passing directory with images via command line argument now isn't - required -- it there's no such directory specified standard open - dialog might be used for this (before application used to abort - due to accessing to non-existing list element). - - Conversion of source images to grayscale now happens correct. - It was needed to build grayscale palette for 8bit indexed buffer. - -commit 05f1a0a78ad8ff6646d1e8da97e6f7575b891536 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Sat Apr 14 17:21:29 2012 +0600 - - Make QtTracker compilable again porting it to recent API change and code cleanup: - - - It was using SAD tracker with own API, now it's using standard RegionTracker API - which should make it easier to switch between different trackers. - - Restored LaplaceFilter from old SAD module which convolves images with the - discrete laplacian operator. - -commit a44312a7beb2963b8e3bf8015c516d2eff40cc3d -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Thu Apr 12 13:56:02 2012 +0600 - - Added solver for modal camera motion, currently supports only tripod solving - - This solver is intended to deal with such camera motions as tripod and panning, - where it's impossible to reconstruct exact position of markers in 3d view. - - It projects markers onto sphere and uses rigid registration of rotation to - find rotation angles which makes bundles from previous and current frame be - as closest as it's possible. diff --git a/extern/libmv/files.txt b/extern/libmv/files.txt index 16afdb36371..d77d0ea8147 100644 --- a/extern/libmv/files.txt +++ b/extern/libmv/files.txt @@ -21,6 +21,7 @@ libmv/multiview/homography.cc libmv/multiview/homography.h libmv/multiview/homography_parameterization.h libmv/multiview/nviewtriangulation.h +libmv/multiview/panography.cc libmv/multiview/panography.h libmv/multiview/projection.cc libmv/multiview/projection.h @@ -36,7 +37,6 @@ libmv/numeric/poly.cc libmv/numeric/poly.h libmv/simple_pipeline/bundle.cc libmv/simple_pipeline/bundle.h -libmv/simple_pipeline/callbacks.cc libmv/simple_pipeline/callbacks.h libmv/simple_pipeline/camera_intrinsics.cc libmv/simple_pipeline/camera_intrinsics.h diff --git a/extern/libmv/libmv/base/vector.h b/extern/libmv/libmv/base/vector.h index c2a3298087a..067db4ba7f7 100644 --- a/extern/libmv/libmv/base/vector.h +++ b/extern/libmv/libmv/base/vector.h @@ -39,7 +39,7 @@ namespace libmv { // - 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 +// 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, diff --git a/extern/libmv/libmv/base/vector_utils.h b/extern/libmv/libmv/base/vector_utils.h index 7a0c3ba24f5..c71e1bea951 100644 --- a/extern/libmv/libmv/base/vector_utils.h +++ b/extern/libmv/libmv/base/vector_utils.h @@ -31,4 +31,4 @@ void DeleteElements(Array *array) { array->clear(); } -#endif // LIBMV_BASE_VECTOR_UTILS_H_ +#endif // LIBMV_BASE_VECTOR_UTILS_H_ diff --git a/extern/libmv/libmv/image/array_nd.cc b/extern/libmv/libmv/image/array_nd.cc index 3a77e3e4881..469a19aabf1 100644 --- a/extern/libmv/libmv/image/array_nd.cc +++ b/extern/libmv/libmv/image/array_nd.cc @@ -35,8 +35,8 @@ void FloatArrayToScaledByteArray(const Array3Df &float_array, 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)); + minval = std::min(minval, float_array(i, j, k)); + maxval = std::max(maxval, float_array(i, j, k)); } } } @@ -47,8 +47,8 @@ void FloatArrayToScaledByteArray(const Array3Df &float_array, 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); + float unscaled = (float_array(i, j, k) - minval) / (maxval - minval); + (*byte_array)(i, j, k) = (unsigned char)(255 * unscaled); } } } @@ -60,7 +60,7 @@ void ByteArrayToScaledFloatArray(const Array3Du &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; + (*float_array)(i, j, k) = float(byte_array(i, j, k)) / 255.0f; } } } diff --git a/extern/libmv/libmv/image/array_nd.h b/extern/libmv/libmv/image/array_nd.h index 6d7570cda9b..f40fadcbde7 100644 --- a/extern/libmv/libmv/image/array_nd.h +++ b/extern/libmv/libmv/image/array_nd.h @@ -57,9 +57,13 @@ class ArrayND : public BaseArray { 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(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); } + ArrayND(T* data, int s0, int s1, int s2) : data_(data), own_data(false) { + Resize(s0, s1, s2); + } /// Destructor deletes pixel data. ~ArrayND() { @@ -93,7 +97,7 @@ class ArrayND : public BaseArray { for (int i = N - 1; i > 0; --i) { strides_(i - 1) = strides_(i) * shape_(i); } - if(own_data) { + if (own_data) { delete [] data_; data_ = NULL; if (Size() > 0) { @@ -103,7 +107,7 @@ class ArrayND : public BaseArray { } template<typename D> - void ResizeLike(const ArrayND<D,N> &other) { + void ResizeLike(const ArrayND<D, N> &other) { Resize(other.Shape()); } @@ -136,12 +140,12 @@ class ArrayND : public BaseArray { /// 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}; + int shape[] = {s0, s1, s2}; Resize(shape); } template<typename D> - void CopyFrom(const ArrayND<D,N> &other) { + void CopyFrom(const ArrayND<D, N> &other) { ResizeLike(other); T *data = Data(); const D *other_data = other.Data(); @@ -238,7 +242,7 @@ class ArrayND : public BaseArray { T &operator()(int i0, int i1) { assert(0 <= i0 && i0 < Shape(0)); assert(0 <= i1 && i1 < Shape(1)); - return *( Data() + Offset(i0,i1) ); + return *(Data() + Offset(i0, i1)); } /// 3D specialization. @@ -246,29 +250,29 @@ class ArrayND : public BaseArray { 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 *(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) ); + return *(Data() + Offset(index)); } /// 1D specialization. const T &operator()(int i0) const { - return *( Data() + Offset(i0) ); + 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) ); + return *(Data() + Offset(i0, i1)); } /// 3D specialization. const T &operator()(int i0, int i1, int i2) const { - return *( Data() + Offset(i0,i1,i2) ); + return *(Data() + Offset(i0, i1, i2)); } /// True if index is inside array. @@ -343,14 +347,14 @@ class Array3D : public ArrayND<T, 3> { Array3D() : Base() { } - Array3D(int height, int width, int depth=1) + Array3D(int height, int width, int depth = 1) : Base(height, width, depth) { } - Array3D(T* data, int height, int width, int depth=1) + Array3D(T* data, int height, int width, int depth = 1) : Base(data, height, width, depth) { } - void Resize(int height, int width, int depth=1) { + void Resize(int height, int width, int depth = 1) { Base::Resize(height, width, depth); } @@ -376,12 +380,12 @@ class Array3D : public ArrayND<T, 3> { 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); + 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); + return Base::operator()(i0, i1, i2); } }; @@ -413,13 +417,13 @@ void ByteArrayToScaledFloatArray(const Array3Du &byte_array, Array3Df *float_array); template <typename AArrayType, typename BArrayType, typename CArrayType> -void MultiplyElements( const AArrayType &a, +void MultiplyElements(const AArrayType &a, const BArrayType &b, - CArrayType *c ) { + 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() ); + assert(a.Shape() == b.Shape()); c->ResizeLike(a); // To perform the multiplcation, a "current" index into the N-dimensions of diff --git a/extern/libmv/libmv/image/convolve.cc b/extern/libmv/libmv/image/convolve.cc index 63ff7d6d8ff..4682c619f04 100644 --- a/extern/libmv/libmv/image/convolve.cc +++ b/extern/libmv/libmv/image/convolve.cc @@ -18,10 +18,11 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/image/convolve.h" + #include <cmath> #include "libmv/image/image.h" -#include "libmv/image/convolve.h" namespace libmv { @@ -118,7 +119,7 @@ void Convolve(const Array3Df &in, // fast path. int half_width = kernel.size() / 2; switch (half_width) { -#define static_convolution( size ) case size: \ +#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) @@ -136,13 +137,15 @@ void Convolve(const Array3Df &in, double sum = 0; // Slow path: this loop cannot be unrolled. for (int k = -dynamic_size; k <= dynamic_size; ++k) { - if(vertical) { + if (vertical) { if (y + k >= 0 && y + k < height) { - sum += src[k * src_line_stride] * kernel(2 * dynamic_size - (k + dynamic_size)); + 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)); + sum += src[k * src_stride] * + kernel(2 * dynamic_size - (k + dynamic_size)); } } } @@ -234,25 +237,25 @@ void BoxFilterHorizontal(const Array3Df &in, int half_width = (window_size - 1) / 2; for (int k = 0; k < in.Depth(); ++k) { - for (int i=0; i<in.Height(); ++i) { + for (int i = 0; i < in.Height(); ++i) { float sum = 0; // Init sum. - for (int j=0; j<half_width; ++j) { + 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) { + 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) { + 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) { + for (int j = in.Width() - half_width; j < in.Width(); ++j) { sum -= in(i, j - half_width - 1, k); out(i, j, k) = sum; } @@ -271,22 +274,22 @@ void BoxFilterVertical(const Array3Df &in, for (int j = 0; j < in.Width(); ++j) { float sum = 0; // Init sum. - for (int i=0; i<half_width; ++i) { + 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) { + 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) { + 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) { + for (int i = in.Height() - half_width; i < in.Height(); ++i) { sum -= in(i - half_width - 1, j, k); out(i, j, k) = sum; } @@ -302,18 +305,23 @@ void BoxFilter(const Array3Df &in, BoxFilterVertical(tmp, box_width, out); } -void LaplaceFilter(unsigned char* src, unsigned char* dst, int width, int height, int strength) { - for(int y=1; y<height-1; y++) for(int x=1; x<width-1; x++) { - const unsigned char* s = &src[y*width+x]; - int l = 128 + - s[-width-1] + s[-width] + s[-width+1] + - s[1] - 8*s[0] + s[1] + - s[ width-1] + s[ width] + s[ width+1] ; - int d = ((256-strength)*s[0] + strength*l) / 256; - if(d < 0) d=0; - if(d > 255) d=255; - dst[y*width+x] = d; - } +void LaplaceFilter(unsigned char* src, + unsigned char* dst, + int width, + int height, + int strength) { + for (int y = 1; y < height-1; y++) + for (int x = 1; x < width-1; x++) { + const unsigned char* s = &src[y*width+x]; + int l = 128 + + s[-width-1] + s[-width] + s[-width+1] + + s[1] - 8*s[0] + s[1] + + s[ width-1] + s[ width] + s[ width+1]; + int d = ((256-strength)*s[0] + strength*l) / 256; + if (d < 0) d=0; + if (d > 255) d=255; + dst[y*width+x] = d; + } } } // namespace libmv diff --git a/extern/libmv/libmv/image/convolve.h b/extern/libmv/libmv/image/convolve.h index a005dc31f10..d3b6da9794b 100644 --- a/extern/libmv/libmv/image/convolve.h +++ b/extern/libmv/libmv/image/convolve.h @@ -95,7 +95,11 @@ void BoxFilter(const FloatImage &in, \note Make sure the search region is filtered with the same strength as the pattern. */ -void LaplaceFilter(unsigned char* src, unsigned char* dst, int width, int height, int strength); +void LaplaceFilter(unsigned char* src, + unsigned char* dst, + int width, + int height, + int strength); } // namespace libmv diff --git a/extern/libmv/libmv/image/correlation.h b/extern/libmv/libmv/image/correlation.h index ba64951a167..ac1f8edab49 100644 --- a/extern/libmv/libmv/image/correlation.h +++ b/extern/libmv/libmv/image/correlation.h @@ -26,9 +26,10 @@ namespace libmv { -inline double PearsonProductMomentCorrelation(Array3Df image_and_gradient1_sampled, - Array3Df image_and_gradient2_sampled, - int width) { +inline double PearsonProductMomentCorrelation( + Array3Df image_and_gradient1_sampled, + Array3Df image_and_gradient2_sampled, + int width) { double sX = 0, sY = 0, sXX = 0, sYY = 0, sXY = 0; for (int r = 0; r < width; ++r) { diff --git a/extern/libmv/libmv/image/image.h b/extern/libmv/libmv/image/image.h index d158b0e0397..e0f200a4c93 100644 --- a/extern/libmv/libmv/image/image.h +++ b/extern/libmv/libmv/image/image.h @@ -60,8 +60,7 @@ class Image { // Size in bytes that the image takes in memory. int MemorySizeInBytes() { int size; - switch (array_type_) - { + switch (array_type_) { case BYTE: size = reinterpret_cast<Array3Du *>(array_)->MemorySizeInBytes(); break; @@ -83,8 +82,7 @@ class Image { } ~Image() { - switch (array_type_) - { + switch (array_type_) { case BYTE: delete reinterpret_cast<Array3Du *>(array_); @@ -109,23 +107,22 @@ class Image { Image& operator= (const Image& f) { if (this != &f) { array_type_ = f.array_type_; - switch (array_type_) - { + switch (array_type_) { case BYTE: delete reinterpret_cast<Array3Du *>(array_); - array_ = new Array3Du( *(Array3Du *)f.array_); + array_ = new Array3Du(*(Array3Du *)f.array_); break; case FLOAT: delete reinterpret_cast<Array3Df *>(array_); - array_ = new Array3Df( *(Array3Df *)f.array_); + array_ = new Array3Df(*(Array3Df *)f.array_); break; case INT: delete reinterpret_cast<Array3Di *>(array_); - array_ = new Array3Di( *(Array3Di *)f.array_); + array_ = new Array3Di(*(Array3Di *)f.array_); break; case SHORT: delete reinterpret_cast<Array3Ds *>(array_); - array_ = new Array3Ds( *(Array3Ds *)f.array_); + array_ = new Array3Ds(*(Array3Ds *)f.array_); break; default: assert(0); diff --git a/extern/libmv/libmv/image/sample.h b/extern/libmv/libmv/image/sample.h index a8850effeab..a95d08a9815 100644 --- a/extern/libmv/libmv/image/sample.h +++ b/extern/libmv/libmv/image/sample.h @@ -71,8 +71,8 @@ inline T SampleLinear(const Array3D<T> &image, float y, float x, int v = 0) { const T im21 = image(y2, x1, v); const T im22 = image(y2, x2, v); - return T( dy * ( dx * im11 + (1.0 - dx) * im12 ) + - (1 - dy) * ( dx * im21 + (1.0 - dx) * im22 )); + return T( dy * (dx * im11 + (1.0 - dx) * im12) + + (1 - dy) * (dx * im21 + (1.0 - dx) * im22)); } /// Linear interpolation, of all channels. The sample is assumed to have the @@ -95,8 +95,8 @@ inline void SampleLinear(const Array3D<T> &image, float y, float x, T *sample) { const T im21 = image(y2, x1, i); const T im22 = image(y2, x2, i); - sample[i] = T( dy * ( dx * im11 + (1.0 - dx) * im12 ) + - (1 - dy) * ( dx * im21 + (1.0 - dx) * im22 )); + sample[i] = T( dy * (dx * im11 + (1.0 - dx) * im12) + + (1 - dy) * (dx * im21 + (1.0 - dx) * im22)); } } diff --git a/extern/libmv/libmv/image/tuple.h b/extern/libmv/libmv/image/tuple.h index 79acc9579d0..c8dc36f2e18 100644 --- a/extern/libmv/libmv/image/tuple.h +++ b/extern/libmv/libmv/image/tuple.h @@ -37,10 +37,10 @@ class Tuple { Tuple(D *values) { Reset(values); } template <typename D> - Tuple(const Tuple<D,N> &b) { Reset(b); } + Tuple(const Tuple<D, N> &b) { Reset(b); } template <typename D> - Tuple& operator=(const Tuple<D,N>& b) { + Tuple& operator=(const Tuple<D, N>& b) { Reset(b); return *this; } @@ -50,14 +50,14 @@ class Tuple { template <typename D> void Reset(D *values) { - for(int i=0;i<N;i++) { + 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++) { + for (int i = 0;i < N; i++) { data_[i] = value; } } diff --git a/extern/libmv/libmv/multiview/conditioning.cc b/extern/libmv/libmv/multiview/conditioning.cc index 20e3a88e6cb..0afbf119ea3 100644 --- a/extern/libmv/libmv/multiview/conditioning.cc +++ b/extern/libmv/libmv/multiview/conditioning.cc @@ -22,7 +22,7 @@ #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; @@ -66,7 +66,7 @@ void ApplyTransformationToPoints(const Mat &points, const Mat3 &T, Mat *transformed_points) { int n = points.cols(); - transformed_points->resize(2,n); + transformed_points->resize(2, n); Mat3X p(3, n); EuclideanToHomogeneous(points, &p); p = T * p; @@ -96,4 +96,4 @@ void UnnormalizerI::Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H) { *H = T2.inverse() * (*H) * T1; } -} // namespace libmv +} // namespace libmv diff --git a/extern/libmv/libmv/multiview/conditioning.h b/extern/libmv/libmv/multiview/conditioning.h index 181d7485374..8f3e3a76070 100644 --- a/extern/libmv/libmv/multiview/conditioning.h +++ b/extern/libmv/libmv/multiview/conditioning.h @@ -54,7 +54,6 @@ struct UnnormalizerT { static void Unnormalize(const Mat3 &T1, const Mat3 &T2, Mat3 *H); }; -} //namespace libmv +} // namespace libmv - -#endif // LIBMV_MULTIVIEW_CONDITIONNING_H_ +#endif // LIBMV_MULTIVIEW_CONDITIONNING_H_ diff --git a/extern/libmv/libmv/multiview/euclidean_resection.cc b/extern/libmv/libmv/multiview/euclidean_resection.cc index 062c8b9067c..10c7330770f 100644 --- a/extern/libmv/libmv/multiview/euclidean_resection.cc +++ b/extern/libmv/libmv/multiview/euclidean_resection.cc @@ -18,6 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/multiview/euclidean_resection.h" + #include <cmath> #include <limits> @@ -26,7 +28,6 @@ #include "libmv/base/vector.h" #include "libmv/logging/logging.h" -#include "libmv/multiview/euclidean_resection.h" #include "libmv/multiview/projection.h" namespace libmv { @@ -34,7 +35,7 @@ namespace euclidean_resection { typedef unsigned int uint; -bool EuclideanResection(const Mat2X &x_camera, +bool EuclideanResection(const Mat2X &x_camera, const Mat3X &X_world, Mat3 *R, Vec3 *t, ResectionMethod method, @@ -52,7 +53,7 @@ bool EuclideanResection(const Mat2X &x_camera, return false; } -bool EuclideanResection(const Mat &x_image, +bool EuclideanResection(const Mat &x_image, const Mat3X &X_world, const Mat3 &K, Mat3 *R, Vec3 *t, @@ -80,11 +81,11 @@ void AbsoluteOrientation(const Mat3X &X, // Normalize the two point sets. Mat3X Xn(3, num_points), Xpn(3, num_points); - for( int i = 0; i < num_points; ++i ){ + 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)); @@ -101,7 +102,7 @@ void AbsoluteOrientation(const Mat3X &X, 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); @@ -180,12 +181,12 @@ static Vec MatrixToConstraint(const Mat &A, C.setZero(); int idx = 0; for (int i = 0; i < num_lambda; ++i) { - for( int j = i; j < num_lambda; ++j) { + for (int j = i; j < num_lambda; ++j) { C(idx) = A(i, j); - if (i != j){ + if (i != j) { C(idx) += A(j, i); } - ++ idx; + ++idx; } } return C; @@ -194,14 +195,14 @@ static Vec MatrixToConstraint(const Mat &A, // Normalizes the columns of vectors. static void NormalizeColumnVectors(Mat3X *vectors) { int num_columns = vectors->cols(); - for (int i = 0; i < num_columns; ++i){ + for (int i = 0; i < num_columns; ++i) { vectors->col(i).normalize(); } } -void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, - const Mat3X &X_world, - Mat3 *R, +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); @@ -214,7 +215,7 @@ void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, 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; @@ -224,7 +225,7 @@ void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, // 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; + 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)); @@ -243,7 +244,7 @@ void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, } int num_lambda = num_points + 1; // Dimension of the null space of M. - Mat V = M.jacobiSvd(Eigen::ComputeFullV).matrixV().block(0, + Mat V = M.jacobiSvd(Eigen::ComputeFullV).matrixV().block(0, num_m_rows, num_m_columns, num_lambda); @@ -263,12 +264,11 @@ void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, 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 ){ + if (i != j && i != k) { int idx3 = IJToPointIndex(i, j, num_points); int idx4 = IJToPointIndex(i, k, num_points); @@ -318,13 +318,12 @@ void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, 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); @@ -334,7 +333,7 @@ void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, // 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(); @@ -344,7 +343,7 @@ void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, // 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 ) { + 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. @@ -363,17 +362,17 @@ static void SelectControlPoints(const Mat3X &X_world, X_control_points->col(0) = mean; // Computes PCA - X_centered->resize (3, num_points); + X_centered->resize(3, num_points); for (size_t c = 0; c < num_points; c++) { - X_centered->col(c) = X_world.col (c) - mean; + 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); + double k = sqrt(w(c) / num_points); + X_control_points->col(c + 1) = mean + k * u.col(c); } } @@ -382,7 +381,7 @@ static void ComputeBarycentricCoordinates(const Mat3X &X_world_centered, const Mat34 &X_control_points, Mat4X *alphas) { size_t num_points = X_world_centered.cols(); - Mat3 C2 ; + Mat3 C2; for (size_t c = 1; c < 4; c++) { C2.col(c-1) = X_control_points.col(c) - X_control_points.col(0); } @@ -400,7 +399,7 @@ static void ComputeBarycentricCoordinates(const Mat3X &X_world_centered, // Estimates the coordinates of all real points in the camera coordinate frame static void ComputePointsCoordinatesInCameraFrame( - const Mat4X &alphas, + const Mat4X &alphas, const Vec4 &betas, const Eigen::Matrix<double, 12, 12> &U, Mat3X *X_camera) { @@ -423,7 +422,7 @@ static void ComputePointsCoordinatesInCameraFrame( // 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) { + if ((*X_camera)(2, i) < 0) { num_z_neg++; } } @@ -432,7 +431,7 @@ static void ComputePointsCoordinatesInCameraFrame( if (num_z_neg > 0.5 * X_camera->cols()) { C2b = -C2b; *X_camera = -(*X_camera); - } + } } bool EuclideanResectionEPnP(const Mat2X &x_camera, @@ -442,16 +441,16 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, 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; @@ -462,17 +461,17 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, 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, + M.block(2*c, 0, 2, 12) << a0, 0, a0*(-ui), a1, 0, - a1*(-ui), a2, 0, + a1*(-ui), a2, 0, a2*(-ui), a3, 0, - a3*(-ui), 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(); @@ -495,18 +494,18 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, 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); + 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++) { @@ -520,7 +519,7 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, 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(), @@ -528,7 +527,7 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, (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; @@ -548,7 +547,8 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, // check, is the right approach. So far this seems the case. // // TODO(sergey): Made it an option for now, in some cases it makes sense to - // still fallback to reprojection solution (see bug [#32765] from Blender bug tracker) + // still fallback to reprojection solution + // For details see bug [#32765] from Blender bug tracker // double kSuccessThreshold = std::numeric_limits<double>::max(); double kSuccessThreshold = success_threshold; @@ -559,15 +559,15 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, 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); + 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::JacobiSVD<Mat> svd_of_l4(l_6x4, Eigen::ComputeFullU | Eigen::ComputeFullV); Vec4 b4 = svd_of_l4.solve(rho); if ((l_6x4 * b4).isApprox(rho, kSuccessThreshold)) { 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); @@ -578,14 +578,14 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, 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::JacobiSVD<Mat> svdOfL3(l_6x3, Eigen::ComputeFullU | Eigen::ComputeFullV); Vec3 b3 = svdOfL3.solve(rho); VLOG(2) << " rho = " << rho; @@ -611,14 +611,14 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, 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::JacobiSVD<Mat> svdOfL5(l_6x5, Eigen::ComputeFullU | Eigen::ComputeFullV); Vec5 b5 = svdOfL5.solve(rho); if ((l_6x5 * b5).isApprox(rho, kSuccessThreshold)) { @@ -650,7 +650,7 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, 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(1); @@ -675,5 +675,5 @@ bool EuclideanResectionEPnP(const Mat2X &x_camera, return true; } -} // namespace resection -} // namespace libmv +} // namespace resection +} // namespace libmv diff --git a/extern/libmv/libmv/multiview/euclidean_resection.h b/extern/libmv/libmv/multiview/euclidean_resection.h index b0428ec61fd..1a329702c2a 100644 --- a/extern/libmv/libmv/multiview/euclidean_resection.h +++ b/extern/libmv/libmv/multiview/euclidean_resection.h @@ -26,7 +26,7 @@ namespace libmv { namespace euclidean_resection { - + enum ResectionMethod { RESECTION_ANSAR_DANIILIDIS, @@ -48,7 +48,7 @@ enum ResectionMethod { * \param success_threshold Threshold of an error which is still considered a success * (currently used by EPnP algorithm only) */ -bool EuclideanResection(const Mat2X &x_camera, +bool EuclideanResection(const Mat2X &x_camera, const Mat3X &X_world, Mat3 *R, Vec3 *t, ResectionMethod method = RESECTION_EPNP, @@ -67,7 +67,7 @@ bool EuclideanResection(const Mat2X &x_camera, * \param t Solution for the camera translation vector * \param method Resection method */ -bool EuclideanResection(const Mat &x_image, +bool EuclideanResection(const Mat &x_image, const Mat3X &X_world, const Mat3 &K, Mat3 *R, Vec3 *t, @@ -101,7 +101,7 @@ void AbsoluteOrientation(const Mat3X &X, * 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, +void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, const Mat3X &X_world, Mat3 *R, Vec3 *t); /** @@ -121,12 +121,12 @@ void EuclideanResectionAnsarDaniilidis(const Mat2X &x_camera, * \note: the non-linear optimization is not implemented here. */ bool EuclideanResectionEPnP(const Mat2X &x_camera, - const Mat3X &X_world, + const Mat3X &X_world, Mat3 *R, Vec3 *t, double success_threshold = 1e-3); -} // namespace euclidean_resection -} // namespace libmv +} // 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 index 80f155e804d..96576724150 100644 --- a/extern/libmv/libmv/multiview/fundamental.cc +++ b/extern/libmv/libmv/multiview/fundamental.cc @@ -18,13 +18,14 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/multiview/fundamental.h" + #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 { @@ -304,7 +305,6 @@ void MotionFromEssential(const Mat3 &E, std::vector<Vec3> *ts) { Eigen::JacobiSVD<Mat3> USV(E, Eigen::ComputeFullU | Eigen::ComputeFullV); Mat3 U = USV.matrixU(); - Vec3 d = USV.singularValues(); Mat3 Vt = USV.matrixV().transpose(); // Last column of U is undetermined since d = (a a 0). diff --git a/extern/libmv/libmv/multiview/homography.cc b/extern/libmv/libmv/multiview/homography.cc index 538c62598c0..317eb3f85c6 100644 --- a/extern/libmv/libmv/multiview/homography.cc +++ b/extern/libmv/libmv/multiview/homography.cc @@ -18,8 +18,9 @@ // 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/multiview/homography.h" + +#include "libmv/logging/logging.h" #include "libmv/multiview/homography_parameterization.h" namespace libmv { @@ -55,30 +56,30 @@ static bool Homography2DFromCorrespondencesLinearEuc( Mat b = Mat::Zero(n * 3, 1); for (int i = 0; i < n; ++i) { int j = 3 * i; - L(j, 0) = x1(0, i); // a - L(j, 1) = x1(1, i); // b - L(j, 2) = 1.0; // c - L(j, 6) = -x2(0, i) * x1(0, i); // g - L(j, 7) = -x2(0, i) * x1(1, i); // h - b(j, 0) = x2(0, i); // i + L(j, 0) = x1(0, i); // a + L(j, 1) = x1(1, i); // b + L(j, 2) = 1.0; // c + L(j, 6) = -x2(0, i) * x1(0, i); // g + L(j, 7) = -x2(0, i) * x1(1, i); // h + b(j, 0) = x2(0, i); // i ++j; - L(j, 3) = x1(0, i); // d - L(j, 4) = x1(1, i); // e - L(j, 5) = 1.0; // f - L(j, 6) = -x2(1, i) * x1(0, i); // g - L(j, 7) = -x2(1, i) * x1(1, i); // h - b(j, 0) = x2(1, i); // i - + L(j, 3) = x1(0, i); // d + L(j, 4) = x1(1, i); // e + L(j, 5) = 1.0; // f + L(j, 6) = -x2(1, i) * x1(0, i); // g + L(j, 7) = -x2(1, i) * x1(1, i); // h + b(j, 0) = x2(1, i); // i + // This ensures better stability // TODO(julien) make a lite version without this 3rd set ++j; - L(j, 0) = x2(1, i) * x1(0, i); // a - L(j, 1) = x2(1, i) * x1(1, i); // b - L(j, 2) = x2(1, i); // c - L(j, 3) = -x2(0, i) * x1(0, i); // d - L(j, 4) = -x2(0, i) * x1(1, i); // e - L(j, 5) = -x2(0, i) ; // f + L(j, 0) = x2(1, i) * x1(0, i); // a + L(j, 1) = x2(1, i) * x1(1, i); // b + L(j, 2) = x2(1, i); // c + L(j, 3) = -x2(0, i) * x1(0, i); // d + L(j, 4) = -x2(0, i) * x1(1, i); // e + L(j, 5) = -x2(0, i); // f } // Solve Lx=B Vec h = L.fullPivLu().solve(b); @@ -103,7 +104,7 @@ bool Homography2DFromCorrespondencesLinear(const Mat &x1, Mat3 *H, double expected_precision) { if (x1.rows() == 2) { - return Homography2DFromCorrespondencesLinearEuc(x1, x2, H, + return Homography2DFromCorrespondencesLinearEuc(x1, x2, H, expected_precision); } assert(3 == x1.rows()); @@ -119,29 +120,29 @@ bool Homography2DFromCorrespondencesLinear(const Mat &x1, Mat b = Mat::Zero(n * 3, 1); for (int i = 0; i < n; ++i) { int j = 3 * i; - L(j, 0) = x2(w, i) * x1(x, i);//a - L(j, 1) = x2(w, i) * x1(y, i);//b - L(j, 2) = x2(w, i) * x1(w, i);//c - L(j, 6) = -x2(x, i) * x1(x, i);//g - L(j, 7) = -x2(x, i) * x1(y, i);//h + L(j, 0) = x2(w, i) * x1(x, i); // a + L(j, 1) = x2(w, i) * x1(y, i); // b + L(j, 2) = x2(w, i) * x1(w, i); // c + L(j, 6) = -x2(x, i) * x1(x, i); // g + L(j, 7) = -x2(x, i) * x1(y, i); // h b(j, 0) = x2(x, i) * x1(w, i); ++j; - L(j, 3) = x2(w, i) * x1(x, i);//d - L(j, 4) = x2(w, i) * x1(y, i);//e - L(j, 5) = x2(w, i) * x1(w, i);//f - L(j, 6) = -x2(y, i) * x1(x, i);//g - L(j, 7) = -x2(y, i) * x1(y, i);//h + L(j, 3) = x2(w, i) * x1(x, i); // d + L(j, 4) = x2(w, i) * x1(y, i); // e + L(j, 5) = x2(w, i) * x1(w, i); // f + L(j, 6) = -x2(y, i) * x1(x, i); // g + L(j, 7) = -x2(y, i) * x1(y, i); // h b(j, 0) = x2(y, i) * x1(w, i); // This ensures better stability ++j; - L(j, 0) = x2(y, i) * x1(x, i);//a - L(j, 1) = x2(y, i) * x1(y, i);//b - L(j, 2) = x2(y, i) * x1(w, i);//c - L(j, 3) = -x2(x, i) * x1(x, i);//d - L(j, 4) = -x2(x, i) * x1(y, i);//e - L(j, 5) = -x2(x, i) * x1(w, i);//f + L(j, 0) = x2(y, i) * x1(x, i); // a + L(j, 1) = x2(y, i) * x1(y, i); // b + L(j, 2) = x2(y, i) * x1(w, i); // c + L(j, 3) = -x2(x, i) * x1(x, i); // d + L(j, 4) = -x2(x, i) * x1(y, i); // e + L(j, 5) = -x2(x, i) * x1(w, i); // f } // Solve Lx=B Vec h = L.fullPivLu().solve(b); @@ -165,11 +166,11 @@ bool Homography2DFromCorrespondencesLinear(const Mat &x1, * |0 0 0 1| -> |-x2w| |-1 0 0 0| -> | x2x| |0 0 0 0| -> | 0 | * |0 0 0 0| | 0 | | 0 0 0 0| | 0 | |0 0 0 1| |-x2w| * |0-1 0 0| | x2y| | 0 0 0 0| | 0 | |0 0-1 0| | x2z| - * |a b c d| - * A = |e f g h| + * |a b c d| + * A = |e f g h| * |i j k l| - * |m n o 1| - * + * |m n o 1| + * * x2^t * H1 * A *x1 = (-x2w*a +x2x*m )*x1x + (-x2w*b +x2x*n )*x1y + (-x2w*c +x2x*o )*x1z + (-x2w*d +x2x*1 )*x1w = 0 * x2^t * H2 * A *x1 = (-x2z*e +x2y*i )*x1x + (-x2z*f +x2y*j )*x1y + (-x2z*g +x2y*k )*x1z + (-x2z*h +x2y*l )*x1w = 0 * x2^t * H3 * A *x1 = (-x2z*a +x2x*i )*x1x + (-x2z*b +x2x*j )*x1y + (-x2z*c +x2x*k )*x1z + (-x2z*d +x2x*l )*x1w = 0 @@ -196,64 +197,64 @@ bool Homography3DFromCorrespondencesLinear(const Mat &x1, Mat b = Mat::Zero(n * 6, 1); for (int i = 0; i < n; ++i) { int j = 6 * i; - L(j, 0) = -x2(w, i) * x1(x, i);//a - L(j, 1) = -x2(w, i) * x1(y, i);//b - L(j, 2) = -x2(w, i) * x1(z, i);//c - L(j, 3) = -x2(w, i) * x1(w, i);//d - L(j,12) = x2(x, i) * x1(x, i);//m - L(j,13) = x2(x, i) * x1(y, i);//n - L(j,14) = x2(x, i) * x1(z, i);//o - b(j, 0) = -x2(x, i) * x1(w, i); - + L(j, 0) = -x2(w, i) * x1(x, i); // a + L(j, 1) = -x2(w, i) * x1(y, i); // b + L(j, 2) = -x2(w, i) * x1(z, i); // c + L(j, 3) = -x2(w, i) * x1(w, i); // d + L(j, 12) = x2(x, i) * x1(x, i); // m + L(j, 13) = x2(x, i) * x1(y, i); // n + L(j, 14) = x2(x, i) * x1(z, i); // o + b(j, 0) = -x2(x, i) * x1(w, i); + ++j; - L(j, 4) = -x2(z, i) * x1(x, i);//e - L(j, 5) = -x2(z, i) * x1(y, i);//f - L(j, 6) = -x2(z, i) * x1(z, i);//g - L(j, 7) = -x2(z, i) * x1(w, i);//h - L(j, 8) = x2(y, i) * x1(x, i);//i - L(j, 9) = x2(y, i) * x1(y, i);//j - L(j,10) = x2(y, i) * x1(z, i);//k - L(j,11) = x2(y, i) * x1(w, i);//l - + L(j, 4) = -x2(z, i) * x1(x, i); // e + L(j, 5) = -x2(z, i) * x1(y, i); // f + L(j, 6) = -x2(z, i) * x1(z, i); // g + L(j, 7) = -x2(z, i) * x1(w, i); // h + L(j, 8) = x2(y, i) * x1(x, i); // i + L(j, 9) = x2(y, i) * x1(y, i); // j + L(j, 10) = x2(y, i) * x1(z, i); // k + L(j, 11) = x2(y, i) * x1(w, i); // l + ++j; - L(j, 0) = -x2(z, i) * x1(x, i);//a - L(j, 1) = -x2(z, i) * x1(y, i);//b - L(j, 2) = -x2(z, i) * x1(z, i);//c - L(j, 3) = -x2(z, i) * x1(w, i);//d - L(j, 8) = x2(x, i) * x1(x, i);//i - L(j, 9) = x2(x, i) * x1(y, i);//j - L(j,10) = x2(x, i) * x1(z, i);//k - L(j,11) = x2(x, i) * x1(w, i);//l - + L(j, 0) = -x2(z, i) * x1(x, i); // a + L(j, 1) = -x2(z, i) * x1(y, i); // b + L(j, 2) = -x2(z, i) * x1(z, i); // c + L(j, 3) = -x2(z, i) * x1(w, i); // d + L(j, 8) = x2(x, i) * x1(x, i); // i + L(j, 9) = x2(x, i) * x1(y, i); // j + L(j, 10) = x2(x, i) * x1(z, i); // k + L(j, 11) = x2(x, i) * x1(w, i); // l + ++j; - L(j, 4) = -x2(w, i) * x1(x, i);//e - L(j, 5) = -x2(w, i) * x1(y, i);//f - L(j, 6) = -x2(w, i) * x1(z, i);//g - L(j, 7) = -x2(w, i) * x1(w, i);//h - L(j,12) = x2(y, i) * x1(x, i);//m - L(j,13) = x2(y, i) * x1(y, i);//n - L(j,14) = x2(y, i) * x1(z, i);//o - b(j, 0) = -x2(y, i) * x1(w, i); - + L(j, 4) = -x2(w, i) * x1(x, i); // e + L(j, 5) = -x2(w, i) * x1(y, i); // f + L(j, 6) = -x2(w, i) * x1(z, i); // g + L(j, 7) = -x2(w, i) * x1(w, i); // h + L(j, 12) = x2(y, i) * x1(x, i); // m + L(j, 13) = x2(y, i) * x1(y, i); // n + L(j, 14) = x2(y, i) * x1(z, i); // o + b(j, 0) = -x2(y, i) * x1(w, i); + ++j; - L(j, 0) = -x2(y, i) * x1(x, i);//a - L(j, 1) = -x2(y, i) * x1(y, i);//b - L(j, 2) = -x2(y, i) * x1(z, i);//c - L(j, 3) = -x2(y, i) * x1(w, i);//d - L(j, 4) = x2(x, i) * x1(x, i);//e - L(j, 5) = x2(x, i) * x1(y, i);//f - L(j, 6) = x2(x, i) * x1(z, i);//g - L(j, 7) = x2(x, i) * x1(w, i);//h - + L(j, 0) = -x2(y, i) * x1(x, i); // a + L(j, 1) = -x2(y, i) * x1(y, i); // b + L(j, 2) = -x2(y, i) * x1(z, i); // c + L(j, 3) = -x2(y, i) * x1(w, i); // d + L(j, 4) = x2(x, i) * x1(x, i); // e + L(j, 5) = x2(x, i) * x1(y, i); // f + L(j, 6) = x2(x, i) * x1(z, i); // g + L(j, 7) = x2(x, i) * x1(w, i); // h + ++j; - L(j, 8) = -x2(w, i) * x1(x, i);//i - L(j, 9) = -x2(w, i) * x1(y, i);//j - L(j,10) = -x2(w, i) * x1(z, i);//k - L(j,11) = -x2(w, i) * x1(w, i);//l - L(j,12) = x2(z, i) * x1(x, i);//m - L(j,13) = x2(z, i) * x1(y, i);//n - L(j,14) = x2(z, i) * x1(z, i);//o - b(j, 0) = -x2(z, i) * x1(w, i); + L(j, 8) = -x2(w, i) * x1(x, i); // i + L(j, 9) = -x2(w, i) * x1(y, i); // j + L(j, 10) = -x2(w, i) * x1(z, i); // k + L(j, 11) = -x2(w, i) * x1(w, i); // l + L(j, 12) = x2(z, i) * x1(x, i); // m + L(j, 13) = x2(z, i) * x1(y, i); // n + L(j, 14) = x2(z, i) * x1(z, i); // o + b(j, 0) = -x2(z, i) * x1(w, i); } // Solve Lx=B Vec h = L.fullPivLu().solve(b); diff --git a/extern/libmv/libmv/multiview/homography.h b/extern/libmv/libmv/multiview/homography.h index a295c4366b6..8d2dff930eb 100644 --- a/extern/libmv/libmv/multiview/homography.h +++ b/extern/libmv/libmv/multiview/homography.h @@ -50,12 +50,12 @@ namespace libmv { bool Homography2DFromCorrespondencesLinear(const Mat &x1, const Mat &x2, Mat3 *H, - double expected_precision = + double expected_precision = EigenDouble::dummy_precision()); /** * 3D Homography transformation estimation. - * + * * This function can be used in order to estimate the homography transformation * from a list of 3D correspondences. * @@ -68,16 +68,16 @@ bool Homography2DFromCorrespondencesLinear(const Mat &x1, * |m n o 1| * \param[in] expected_precision The expected precision in order for instance * to accept almost homography matrices. - * + * * \return true if the transformation estimation has succeeded - * + * * \note Need at least 5 non coplanar points * \note Points coordinates must be in homogeneous coordinates */ bool Homography3DFromCorrespondencesLinear(const Mat &x1, const Mat &x2, Mat4 *H, - double expected_precision = + double expected_precision = EigenDouble::dummy_precision()); /** @@ -87,6 +87,6 @@ bool Homography3DFromCorrespondencesLinear(const Mat &x1, */ double SymmetricGeometricDistance(Mat3 &H, Vec2 &x1, Vec2 &x2); -} // namespace libmv +} // namespace libmv #endif // LIBMV_MULTIVIEW_HOMOGRAPHY_H_ diff --git a/extern/libmv/libmv/multiview/homography_parameterization.h b/extern/libmv/libmv/multiview/homography_parameterization.h index b31642eea15..ca8fbd8066e 100644 --- a/extern/libmv/libmv/multiview/homography_parameterization.h +++ b/extern/libmv/libmv/multiview/homography_parameterization.h @@ -1,15 +1,15 @@ // Copyright (c) 2011 libmv authors. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -40,7 +40,7 @@ class Homography2DNormalizedParameterization { typedef Eigen::Matrix<T, 3, 3> Parameterized; // H /// Convert from the 8 parameters to a H matrix. - static void To(const Parameters &p, Parameterized *h) { + static void To(const Parameters &p, Parameterized *h) { *h << p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), 1.0; @@ -70,7 +70,7 @@ class Homography3DNormalizedParameterization { typedef Eigen::Matrix<T, 4, 4> Parameterized; // H /// Convert from the 15 parameters to a H matrix. - static void To(const Parameters &p, Parameterized *h) { + static void To(const Parameters &p, Parameterized *h) { *h << p(0), p(1), p(2), p(3), p(4), p(5), p(6), p(7), p(8), p(9), p(10), p(11), @@ -86,6 +86,6 @@ class Homography3DNormalizedParameterization { } }; -} // namespace libmv +} // namespace libmv #endif // LIBMV_MULTIVIEW_HOMOGRAPHY_PARAMETERIZATION_H_ diff --git a/extern/libmv/libmv/multiview/nviewtriangulation.h b/extern/libmv/libmv/multiview/nviewtriangulation.h index b4f521f185d..f4614ab1a5c 100644 --- a/extern/libmv/libmv/multiview/nviewtriangulation.h +++ b/extern/libmv/libmv/multiview/nviewtriangulation.h @@ -1,15 +1,15 @@ // 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 @@ -17,7 +17,7 @@ // 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. -// +// // Compute a 3D position of a point from several images of it. In particular, // compute the projective point X in R^4 such that x = PX. // diff --git a/extern/libmv/libmv/multiview/panography.cc b/extern/libmv/libmv/multiview/panography.cc new file mode 100644 index 00000000000..b62802948c4 --- /dev/null +++ b/extern/libmv/libmv/multiview/panography.cc @@ -0,0 +1,125 @@ +// 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 "libmv/multiview/panography.h" + +namespace libmv { + +static bool Build_Minimal2Point_PolynomialFactor( + const Mat & x1, const Mat & x2, + double * P) { // P must be a double[4] + assert(2 == x1.rows()); + assert(2 == x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + // Setup the variable of the input problem: + Vec xx1 = (x1.col(0)).transpose(); + Vec yx1 = (x1.col(1)).transpose(); + + double a12 = xx1.dot(yx1); + Vec xx2 = (x2.col(0)).transpose(); + Vec yx2 = (x2.col(1)).transpose(); + double b12 = xx2.dot(yx2); + + double a1 = xx1.squaredNorm(); + double a2 = yx1.squaredNorm(); + + double b1 = xx2.squaredNorm(); + double b2 = yx2.squaredNorm(); + + // Build the 3rd degre polynomial in F^2. + // + // f^6 * p + f^4 * q + f^2* r + s = 0; + // + // Coefficients in ascending powers of alpha, i.e. P[N]*x^N. + // Run panography_coeffs.py to get the below coefficients. + P[0] = b1*b2*a12*a12-a1*a2*b12*b12; + P[1] = -2*a1*a2*b12+2*a12*b1*b2+b1*a12*a12+b2*a12*a12-a1*b12*b12-a2*b12*b12; + P[2] = b1*b2-a1*a2-2*a1*b12-2*a2*b12+2*a12*b1+2*a12*b2+a12*a12-b12*b12; + P[3] = b1+b2-2*b12-a1-a2+2*a12; + + // If P[3] equal to 0 we get ill conditionned data + return (P[3] != 0.0); +} + +// This implements a minimal solution (2 points) for panoramic stitching: +// +// http://www.cs.ubc.ca/~mbrown/minimal/minimal.html +// +// [1] M. Brown and R. Hartley and D. Nister. Minimal Solutions for Panoramic +// Stitching. CVPR07. +void F_FromCorrespondance_2points(const Mat &x1, const Mat &x2, + vector<double> *fs) { + // Build Polynomial factor to get squared focal value. + double P[4]; + Build_Minimal2Point_PolynomialFactor(x1, x2, &P[0]); + + // Solve it by using F = f^2 and a Cubic polynomial solver + // + // F^3 * p + F^2 * q + F^1 * r + s = 0 + // + double roots[3]; + int num_roots = SolveCubicPolynomial(P, roots); + for (int i = 0; i < num_roots; ++i) { + if (roots[i] > 0.0) { + fs->push_back(sqrt(roots[i])); + } + } +} + +// Compute the 3x3 rotation matrix that fits two 3D point clouds in the least +// square sense. The method is from: +// +// K. Arun,T. Huand and D. Blostein. Least-squares fitting of 2 3-D point +// sets. IEEE Transactions on Pattern Analysis and Machine Intelligence, +// 9:698-700, 1987. +void GetR_FixedCameraCenter(const Mat &x1, const Mat &x2, + const double focal, + Mat3 *R) { + assert(3 == x1.rows()); + assert(2 <= x1.cols()); + assert(x1.rows() == x2.rows()); + assert(x1.cols() == x2.cols()); + + // Build simplified K matrix + Mat3 K(Mat3::Identity() * 1.0/focal); + K(2, 2)= 1.0; + + // Build the correlation matrix; equation (22) in [1]. + Mat3 C = Mat3::Zero(); + for (int i = 0; i < x1.cols(); ++i) { + Mat r1i = (K * x1.col(i)).normalized(); + Mat r2i = (K * x2.col(i)).normalized(); + C += r2i * r1i.transpose(); + } + + // Solve for rotation. Equations (24) and (25) in [1]. + Eigen::JacobiSVD<Mat> svd(C, Eigen::ComputeThinU | Eigen::ComputeThinV); + Mat3 scale = Mat3::Identity(); + scale(2, 2) = ((svd.matrixU() * svd.matrixV().transpose()).determinant() > 0.0) + ? 1.0 + : -1.0; + + (*R) = svd.matrixU() * scale * svd.matrixV().transpose(); +} + +} // namespace libmv diff --git a/extern/libmv/libmv/multiview/panography.h b/extern/libmv/libmv/multiview/panography.h index 6f01beb0ffd..6e87bd71304 100644 --- a/extern/libmv/libmv/multiview/panography.h +++ b/extern/libmv/libmv/multiview/panography.h @@ -28,45 +28,6 @@ namespace libmv { -static bool Build_Minimal2Point_PolynomialFactor( - const Mat & x1, const Mat & x2, - double * P) //P must be a double[4] -{ - assert(2 == x1.rows()); - assert(2 == x1.cols()); - assert(x1.rows() == x2.rows()); - assert(x1.cols() == x2.cols()); - - // Setup the variable of the input problem: - Vec xx1 = (x1.col(0)).transpose(); - Vec yx1 = (x1.col(1)).transpose(); - - double a12 = xx1.dot(yx1); - Vec xx2 = (x2.col(0)).transpose(); - Vec yx2 = (x2.col(1)).transpose(); - double b12 = xx2.dot(yx2); - - double a1 = xx1.squaredNorm(); - double a2 = yx1.squaredNorm(); - - double b1 = xx2.squaredNorm(); - double b2 = yx2.squaredNorm(); - - // Build the 3rd degre polynomial in F^2. - // - // f^6 * p + f^4 * q + f^2* r + s = 0; - // - // Coefficients in ascending powers of alpha, i.e. P[N]*x^N. - // Run panography_coeffs.py to get the below coefficients. - P[0] = b1*b2*a12*a12-a1*a2*b12*b12; - P[1] = -2*a1*a2*b12+2*a12*b1*b2+b1*a12*a12+b2*a12*a12-a1*b12*b12-a2*b12*b12; - P[2] = b1*b2-a1*a2-2*a1*b12-2*a2*b12+2*a12*b1+2*a12*b2+a12*a12-b12*b12; - P[3] = b1+b2-2*b12-a1-a2+2*a12; - - // If P[3] equal to 0 we get ill conditionned data - return (P[3] != 0.0); -} - // This implements a minimal solution (2 points) for panoramic stitching: // // http://www.cs.ubc.ca/~mbrown/minimal/minimal.html @@ -92,25 +53,8 @@ static bool Build_Minimal2Point_PolynomialFactor( // K = [0 f 0] // [0 0 1] // -static void F_FromCorrespondance_2points(const Mat &x1, const Mat &x2, - vector<double> *fs) { - - // Build Polynomial factor to get squared focal value. - double P[4]; - Build_Minimal2Point_PolynomialFactor(x1, x2, &P[0]); - - // Solve it by using F = f^2 and a Cubic polynomial solver - // - // F^3 * p + F^2 * q + F^1 * r + s = 0 - // - double roots[3]; - int num_roots = SolveCubicPolynomial(P, roots); - for (int i = 0; i < num_roots; ++i) { - if (roots[i] > 0.0) { - fs->push_back(sqrt(roots[i])); - } - } -} +void F_FromCorrespondance_2points(const Mat &x1, const Mat &x2, + vector<double> *fs); // Compute the 3x3 rotation matrix that fits two 3D point clouds in the least // square sense. The method is from: @@ -146,36 +90,10 @@ static void F_FromCorrespondance_2points(const Mat &x1, const Mat &x2, // // R = arg min || X2 - R * x1 || // -static void GetR_FixedCameraCenter(const Mat &x1, const Mat &x2, - const double focal, - Mat3 *R) { - assert(3 == x1.rows()); - assert(2 <= x1.cols()); - assert(x1.rows() == x2.rows()); - assert(x1.cols() == x2.cols()); - - // Build simplified K matrix - Mat3 K( Mat3::Identity() * 1.0/focal ); - K(2,2)= 1.0; - - // Build the correlation matrix; equation (22) in [1]. - Mat3 C = Mat3::Zero(); - for(int i = 0; i < x1.cols(); ++i) { - Mat r1i = (K * x1.col(i)).normalized(); - Mat r2i = (K * x2.col(i)).normalized(); - C += r2i * r1i.transpose(); - } - - // Solve for rotation. Equations (24) and (25) in [1]. - Eigen::JacobiSVD<Mat> svd(C, Eigen::ComputeThinU | Eigen::ComputeThinV); - Mat3 scale = Mat3::Identity(); - scale(2,2) = ((svd.matrixU() * svd.matrixV().transpose()).determinant() > 0.0) - ? 1.0 - : -1.0; - - (*R) = svd.matrixU() * scale * svd.matrixV().transpose(); -} +void GetR_FixedCameraCenter(const Mat &x1, const Mat &x2, + const double focal, + Mat3 *R); } // namespace libmv -#endif // LIBMV_MULTIVIEW_PANOGRAPHY_H +#endif // LIBMV_MULTIVIEW_PANOGRAPHY_H diff --git a/extern/libmv/libmv/multiview/projection.cc b/extern/libmv/libmv/multiview/projection.cc index a7d1a058e9c..f8bece3de68 100644 --- a/extern/libmv/libmv/multiview/projection.cc +++ b/extern/libmv/libmv/multiview/projection.cc @@ -1,15 +1,15 @@ // 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 @@ -38,10 +38,11 @@ void KRt_From_P(const Mat34 &P, Mat3 *Kp, Mat3 *Rp, Vec3 *tp) { // Set K(2,1) to zero. if (K(2, 1) != 0) { - double c = -K(2,2); - double s = K(2,1); + double c = -K(2, 2); + double s = K(2, 1); double l = sqrt(c * c + s * s); - c /= l; s /= l; + c /= l; + s /= l; Mat3 Qx; Qx << 1, 0, 0, 0, c, -s, @@ -54,7 +55,8 @@ void KRt_From_P(const Mat34 &P, Mat3 *Kp, Mat3 *Rp, Vec3 *tp) { double c = K(2, 2); double s = K(2, 0); double l = sqrt(c * c + s * s); - c /= l; s /= l; + c /= l; + s /= l; Mat3 Qy; Qy << c, 0, s, 0, 1, 0, @@ -67,11 +69,12 @@ void KRt_From_P(const Mat34 &P, Mat3 *Kp, Mat3 *Rp, Vec3 *tp) { double c = -K(1, 1); double s = K(1, 0); double l = sqrt(c * c + s * s); - c /= l; s /= l; + c /= l; + s /= l; Mat3 Qz; - Qz << c,-s, 0, - s, c, 0, - 0, 0, 1; + Qz << c, -s, 0, + s, c, 0, + 0, 0, 1; K = K * Qz; Q = Qz.transpose() * Q; } @@ -83,19 +86,19 @@ void KRt_From_P(const Mat34 &P, Mat3 *Kp, Mat3 *Rp, Vec3 *tp) { // - K(0,0) > 0 // - K(2,2) = 1 // - det(R) = 1 - if (K(2,2) < 0) { + if (K(2, 2) < 0) { K = -K; R = -R; } - if (K(1,1) < 0) { + if (K(1, 1) < 0) { Mat3 S; - S << 1, 0, 0, - 0,-1, 0, - 0, 0, 1; + S << 1, 0, 0, + 0, -1, 0, + 0, 0, 1; K = K * S; R = S * R; } - if (K(0,0) < 0) { + if (K(0, 0) < 0) { Mat3 S; S << -1, 0, 0, 0, 1, 0, @@ -106,13 +109,13 @@ void KRt_From_P(const Mat34 &P, Mat3 *Kp, Mat3 *Rp, Vec3 *tp) { // Compute translation. Vec p(3); - p << P(0,3), P(1,3), P(2,3); + p << P(0, 3), P(1, 3), P(2, 3); // TODO(pau) This sould be done by a SolveLinearSystem(A, b, &x) call. // TODO(keir) use the eigen LU solver syntax... Vec3 t = K.inverse() * p; // scale K so that K(2,2) = 1 - K = K / K(2,2); + K = K / K(2, 2); *Kp = K; *Rp = R; @@ -140,10 +143,10 @@ void ProjectionChangeAspectRatio(const Mat34 &P, 0, aspect_ratio_new / aspect_ratio, 0, 0, 0, 1; Mat34 P_temp; - - ProjectionShiftPrincipalPoint(P, principal_point, Vec2(0,0), &P_temp); + + ProjectionShiftPrincipalPoint(P, principal_point, Vec2(0, 0), &P_temp); P_temp = T * P_temp; - ProjectionShiftPrincipalPoint(P_temp, Vec2(0,0), principal_point, P_new); + ProjectionShiftPrincipalPoint(P_temp, Vec2(0, 0), principal_point, P_new); } void HomogeneousToEuclidean(const Mat &H, Mat *X) { @@ -198,15 +201,15 @@ void EuclideanToHomogeneous(const Vec3 &X, Vec4 *H) { // TODO(julien) Call conditioning.h/ApplyTransformationToPoints ? void EuclideanToNormalizedCamera(const Mat2X &x, const Mat3 &K, Mat2X *n) { - Mat3X x_image_h; - EuclideanToHomogeneous(x, &x_image_h); - Mat3X x_camera_h = K.inverse() * x_image_h; - HomogeneousToEuclidean(x_camera_h, n); + Mat3X x_image_h; + EuclideanToHomogeneous(x, &x_image_h); + Mat3X x_camera_h = K.inverse() * x_image_h; + HomogeneousToEuclidean(x_camera_h, n); } void HomogeneousToNormalizedCamera(const Mat3X &x, const Mat3 &K, Mat2X *n) { - Mat3X x_camera_h = K.inverse() * x; - HomogeneousToEuclidean(x_camera_h, n); + Mat3X x_camera_h = K.inverse() * x; + HomogeneousToEuclidean(x_camera_h, n); } double Depth(const Mat3 &R, const Vec3 &t, const Vec3 &X) { diff --git a/extern/libmv/libmv/multiview/projection.h b/extern/libmv/libmv/multiview/projection.h index bc353b64c08..3220bc2dbbc 100644 --- a/extern/libmv/libmv/multiview/projection.h +++ b/extern/libmv/libmv/multiview/projection.h @@ -94,7 +94,7 @@ inline Vec3 EuclideanToHomogeneous(const Vec2 &x) { inline Vec4 EuclideanToHomogeneous(const Vec3 &x) { return Vec4(x(0), x(1), x(2), 1); } -// Conversion from image coordinates to normalized camera coordinates +// Conversion from image coordinates to normalized camera coordinates void EuclideanToNormalizedCamera(const Mat2X &x, const Mat3 &K, Mat2X *n); void HomogeneousToNormalizedCamera(const Mat3X &x, const Mat3 &K, Mat2X *n); @@ -180,16 +180,16 @@ double Depth(const Mat3 &R, const Vec3 &t, const Vec4 &X); * Returns true if the homogenious 3D point X is in front of * the camera P. */ -inline bool isInFrontOfCamera(const Mat34 &P, const Vec4 &X){ +inline bool isInFrontOfCamera(const Mat34 &P, const Vec4 &X) { double condition_1 = P.row(2).dot(X) * X[3]; double condition_2 = X[2] * X[3]; - if( condition_1 > 0 && condition_2 > 0 ) + if (condition_1 > 0 && condition_2 > 0) return true; else return false; } -inline bool isInFrontOfCamera(const Mat34 &P, const Vec3 &X){ +inline bool isInFrontOfCamera(const Mat34 &P, const Vec3 &X) { Vec4 X_homo; X_homo.segment<3>(0) = X; X_homo(3) = 1; @@ -200,14 +200,14 @@ inline bool isInFrontOfCamera(const Mat34 &P, const Vec3 &X){ * Transforms a 2D point from pixel image coordinates to a 2D point in * normalized image coordinates. */ -inline Vec2 ImageToNormImageCoordinates(Mat3 &Kinverse, Vec2 &x){ +inline Vec2 ImageToNormImageCoordinates(Mat3 &Kinverse, Vec2 &x) { Vec3 x_h = Kinverse*EuclideanToHomogeneous(x); return HomogeneousToEuclidean( x_h ); } /// Estimates the root mean square error (2D) -inline double RootMeanSquareError(const Mat2X &x_image, - const Mat4X &X_world, +inline double RootMeanSquareError(const Mat2X &x_image, + const Mat4X &X_world, const Mat34 &P) { size_t num_points = x_image.cols(); Mat2X dx = Project(P, X_world) - x_image; @@ -215,10 +215,10 @@ inline double RootMeanSquareError(const Mat2X &x_image, } /// Estimates the root mean square error (2D) -inline double RootMeanSquareError(const Mat2X &x_image, - const Mat3X &X_world, - const Mat3 &K, - const Mat3 &R, +inline double RootMeanSquareError(const Mat2X &x_image, + const Mat3X &X_world, + const Mat3 &K, + const Mat3 &R, const Vec3 &t) { Mat34 P; P_From_KRt(K, R, t, &P); @@ -226,6 +226,6 @@ inline double RootMeanSquareError(const Mat2X &x_image, Mat2X dx = Project(P, X_world) - x_image; return dx.norm() / num_points; } -} // namespace libmv +} // namespace libmv #endif // LIBMV_MULTIVIEW_PROJECTION_H_ diff --git a/extern/libmv/libmv/multiview/resection.h b/extern/libmv/libmv/multiview/resection.h index e4623899147..c142d6deeb2 100644 --- a/extern/libmv/libmv/multiview/resection.h +++ b/extern/libmv/libmv/multiview/resection.h @@ -1,15 +1,15 @@ // 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 @@ -17,7 +17,7 @@ // 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. -// +// // Compute the projection matrix from a set of 3D points X and their // projections x = PX in 2D. This is useful if a point cloud is reconstructed. // @@ -46,10 +46,10 @@ void Resection(const Matrix<T, 2, Dynamic> &x, T xi = x(0, i); T yi = x(1, i); // See equation (7.2) on page 179 of H&Z. - design.template block<1,4>(2*i, 4) = -X.col(i).transpose(); - design.template block<1,4>(2*i, 8) = yi*X.col(i).transpose(); - design.template block<1,4>(2*i + 1, 0) = X.col(i).transpose(); - design.template block<1,4>(2*i + 1, 8) = -xi*X.col(i).transpose(); + design.template block<1, 4>(2*i, 4) = -X.col(i).transpose(); + design.template block<1, 4>(2*i, 8) = yi*X.col(i).transpose(); + design.template block<1, 4>(2*i + 1, 0) = X.col(i).transpose(); + design.template block<1, 4>(2*i + 1, 8) = -xi*X.col(i).transpose(); } Matrix<T, 12, 1> p; Nullspace(&design, &p); diff --git a/extern/libmv/libmv/multiview/triangulation.cc b/extern/libmv/libmv/multiview/triangulation.cc index b9d38cef936..4d146c8f21b 100644 --- a/extern/libmv/libmv/multiview/triangulation.cc +++ b/extern/libmv/libmv/multiview/triangulation.cc @@ -1,15 +1,15 @@ // 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 @@ -18,9 +18,10 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/multiview/triangulation.h" + #include "libmv/numeric/numeric.h" #include "libmv/multiview/projection.h" -#include "libmv/multiview/triangulation.h" namespace libmv { @@ -30,10 +31,10 @@ void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, Vec4 *X_homogeneous) { Mat4 design; for (int i = 0; i < 4; ++i) { - design(0,i) = x1(0) * P1(2,i) - P1(0,i); - design(1,i) = x1(1) * P1(2,i) - P1(1,i); - design(2,i) = x2(0) * P2(2,i) - P2(0,i); - design(3,i) = x2(1) * P2(2,i) - P2(1,i); + design(0, i) = x1(0) * P1(2, i) - P1(0, i); + design(1, i) = x1(1) * P1(2, i) - P1(1, i); + design(2, i) = x2(0) * P2(2, i) - P2(0, i); + design(3, i) = x2(1) * P2(2, i) - P2(1, i); } Nullspace(&design, X_homogeneous); } diff --git a/extern/libmv/libmv/multiview/triangulation.h b/extern/libmv/libmv/multiview/triangulation.h index c35774d9e1b..be878890242 100644 --- a/extern/libmv/libmv/multiview/triangulation.h +++ b/extern/libmv/libmv/multiview/triangulation.h @@ -1,15 +1,15 @@ // 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 @@ -32,7 +32,7 @@ void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, void TriangulateDLT(const Mat34 &P1, const Vec2 &x1, const Mat34 &P2, const Vec2 &x2, Vec3 *X_euclidean); - -} // namespace libmv + +} // namespace libmv #endif // LIBMV_MULTIVIEW_TRIANGULATION_H_ diff --git a/extern/libmv/libmv/numeric/dogleg.h b/extern/libmv/libmv/numeric/dogleg.h index f05882c1191..bf6f996ddaf 100644 --- a/extern/libmv/libmv/numeric/dogleg.h +++ b/extern/libmv/libmv/numeric/dogleg.h @@ -41,7 +41,7 @@ namespace libmv { template<typename Function, typename Jacobian = NumericJacobian<Function>, typename Solver = Eigen::PartialPivLU< - Matrix<typename Function::FMatrixType::RealScalar, + Matrix<typename Function::FMatrixType::RealScalar, Function::XMatrixType::RowsAtCompileTime, Function::XMatrixType::RowsAtCompileTime> > > class Dogleg { @@ -52,8 +52,8 @@ class Dogleg { typedef Matrix<typename Function::FMatrixType::RealScalar, Function::FMatrixType::RowsAtCompileTime, Function::XMatrixType::RowsAtCompileTime> JMatrixType; - typedef Matrix<typename JMatrixType::RealScalar, - JMatrixType::ColsAtCompileTime, + typedef Matrix<typename JMatrixType::RealScalar, + JMatrixType::ColsAtCompileTime, JMatrixType::ColsAtCompileTime> AMatrixType; enum Status { @@ -75,7 +75,7 @@ class Dogleg { : f_(f), df_(f) {} struct SolverParameters { - SolverParameters() + SolverParameters() : gradient_threshold(1e-16), relative_step_threshold(1e-16), error_threshold(1e-16), diff --git a/extern/libmv/libmv/numeric/function_derivative.h b/extern/libmv/libmv/numeric/function_derivative.h index d7bc437b2e0..9820885f04e 100644 --- a/extern/libmv/libmv/numeric/function_derivative.h +++ b/extern/libmv/libmv/numeric/function_derivative.h @@ -36,7 +36,7 @@ enum NumericJacobianMode { FORWARD, }; -template<typename Function, NumericJacobianMode mode=CENTRAL> +template<typename Function, NumericJacobianMode mode = CENTRAL> class NumericJacobian { public: typedef typename Function::XMatrixType Parameters; @@ -58,7 +58,7 @@ class NumericJacobian { XScalar mean_eps = eps.sum() / eps.rows(); if (mean_eps == XScalar(0)) { // TODO(keir): Do something better here. - mean_eps = 1e-8; // ~sqrt(machine precision). + mean_eps = 1e-8; // ~sqrt(machine precision). } // TODO(keir): Elimininate this needless function evaluation for the // central difference case. diff --git a/extern/libmv/libmv/numeric/levenberg_marquardt.h b/extern/libmv/libmv/numeric/levenberg_marquardt.h index a7877e0270b..2af9a62cf7b 100644 --- a/extern/libmv/libmv/numeric/levenberg_marquardt.h +++ b/extern/libmv/libmv/numeric/levenberg_marquardt.h @@ -40,7 +40,7 @@ namespace libmv { template<typename Function, typename Jacobian = NumericJacobian<Function>, typename Solver = Eigen::PartialPivLU< - Matrix<typename Function::FMatrixType::RealScalar, + Matrix<typename Function::FMatrixType::RealScalar, Function::XMatrixType::RowsAtCompileTime, Function::XMatrixType::RowsAtCompileTime> > > class LevenbergMarquardt { @@ -51,8 +51,8 @@ class LevenbergMarquardt { typedef Matrix<typename Function::FMatrixType::RealScalar, Function::FMatrixType::RowsAtCompileTime, Function::XMatrixType::RowsAtCompileTime> JMatrixType; - typedef Matrix<typename JMatrixType::RealScalar, - JMatrixType::ColsAtCompileTime, + typedef Matrix<typename JMatrixType::RealScalar, + JMatrixType::ColsAtCompileTime, JMatrixType::ColsAtCompileTime> AMatrixType; // TODO(keir): Some of these knobs can be derived from each other and @@ -69,7 +69,7 @@ class LevenbergMarquardt { : f_(f), df_(f) {} struct SolverParameters { - SolverParameters() + SolverParameters() : gradient_threshold(1e-16), relative_step_threshold(1e-16), error_threshold(1e-16), @@ -140,7 +140,7 @@ class LevenbergMarquardt { if (solved && dx.norm() <= params.relative_step_threshold * x.norm()) { results.status = RELATIVE_STEP_SIZE_TOO_SMALL; break; - } + } if (solved) { x_new = x + dx; // Rho is the ratio of the actual reduction in error to the reduction @@ -156,8 +156,8 @@ class LevenbergMarquardt { u = u*std::max(1/3., 1 - (tmp*tmp*tmp)); v = 2; continue; - } - } + } + } // Reject the update because either the normal equations failed to solve // or the local linear model was not good (rho < 0). Instead, increase u // to move closer to gradient descent. diff --git a/extern/libmv/libmv/numeric/numeric.cc b/extern/libmv/libmv/numeric/numeric.cc index 0ca3a64e4f4..9007663c8e2 100644 --- a/extern/libmv/libmv/numeric/numeric.cc +++ b/extern/libmv/libmv/numeric/numeric.cc @@ -121,15 +121,15 @@ void HorizontalStack(const Mat &left, const Mat &right, Mat *stacked) { void MatrixColumn(const Mat &A, int i, Vec2 *v) { assert(A.rows() == 2); - *v << A(0,i), A(1,i); + *v << A(0, i), A(1, i); } void MatrixColumn(const Mat &A, int i, Vec3 *v) { assert(A.rows() == 3); - *v << A(0,i), A(1,i), A(2,i); + *v << A(0, i), A(1, i), A(2, i); } void MatrixColumn(const Mat &A, int i, Vec4 *v) { assert(A.rows() == 4); - *v << A(0,i), A(1,i), A(2,i), A(3,i); + *v << A(0, i), A(1, i), A(2, i), A(3, i); } } // namespace libmv diff --git a/extern/libmv/libmv/numeric/numeric.h b/extern/libmv/libmv/numeric/numeric.h index d2cadf4b579..a95723d59cf 100644 --- a/extern/libmv/libmv/numeric/numeric.h +++ b/extern/libmv/libmv/numeric/numeric.h @@ -34,11 +34,11 @@ #include <Eigen/SVD> #if (defined(_WIN32) || defined(__APPLE__) || defined(__FreeBSD__)) && !defined(__MINGW64__) - void static sincos (double x, double *sinx, double *cosx) { + static void sincos(double x, double *sinx, double *cosx) { *sinx = sin(x); *cosx = cos(x); } -#endif //_WIN32 || __APPLE__ +#endif // _WIN32 || __APPLE__ #if (defined(WIN32) || defined(WIN64)) && !defined(__MINGW32__) inline long lround(double d) { @@ -48,7 +48,7 @@ return (d>0) ? int(d+0.5) : int(d-0.5); } typedef unsigned int uint; -#endif //_WIN32 +#endif // _WIN32 namespace libmv { @@ -86,16 +86,16 @@ typedef Eigen::Matrix<double, 4, 4, Eigen::RowMajor> RMat4; typedef Eigen::Matrix<double, 2, Eigen::Dynamic> Mat2X; typedef Eigen::Matrix<double, 3, Eigen::Dynamic> Mat3X; typedef Eigen::Matrix<double, 4, Eigen::Dynamic> Mat4X; -typedef Eigen::Matrix<double, Eigen::Dynamic, 2> MatX2; -typedef Eigen::Matrix<double, Eigen::Dynamic, 3> MatX3; -typedef Eigen::Matrix<double, Eigen::Dynamic, 4> MatX4; -typedef Eigen::Matrix<double, Eigen::Dynamic, 5> MatX5; -typedef Eigen::Matrix<double, Eigen::Dynamic, 6> MatX6; -typedef Eigen::Matrix<double, Eigen::Dynamic, 7> MatX7; -typedef Eigen::Matrix<double, Eigen::Dynamic, 8> MatX8; -typedef Eigen::Matrix<double, Eigen::Dynamic, 9> MatX9; -typedef Eigen::Matrix<double, Eigen::Dynamic,15> MatX15; -typedef Eigen::Matrix<double, Eigen::Dynamic,16> MatX16; +typedef Eigen::Matrix<double, Eigen::Dynamic, 2> MatX2; +typedef Eigen::Matrix<double, Eigen::Dynamic, 3> MatX3; +typedef Eigen::Matrix<double, Eigen::Dynamic, 4> MatX4; +typedef Eigen::Matrix<double, Eigen::Dynamic, 5> MatX5; +typedef Eigen::Matrix<double, Eigen::Dynamic, 6> MatX6; +typedef Eigen::Matrix<double, Eigen::Dynamic, 7> MatX7; +typedef Eigen::Matrix<double, Eigen::Dynamic, 8> MatX8; +typedef Eigen::Matrix<double, Eigen::Dynamic, 9> MatX9; +typedef Eigen::Matrix<double, Eigen::Dynamic, 15> MatX15; +typedef Eigen::Matrix<double, Eigen::Dynamic, 16> MatX16; typedef Eigen::Vector2d Vec2; typedef Eigen::Vector3d Vec3; @@ -286,18 +286,21 @@ void MeanAndVarianceAlongRows(const Mat &A, #if _WIN32 // TODO(bomboze): un-#if this for both platforms once tested under Windows - /* This solution was extensively discussed here http://forum.kde.org/viewtopic.php?f=74&t=61940 */ - #define SUM_OR_DYNAMIC(x,y) (x==Eigen::Dynamic||y==Eigen::Dynamic)?Eigen::Dynamic:(x+y) + /* This solution was extensively discussed here + http://forum.kde.org/viewtopic.php?f=74&t=61940 */ + #define SUM_OR_DYNAMIC(x, y) (x == Eigen::Dynamic || y == Eigen::Dynamic) ? Eigen::Dynamic : (x+y) template<typename Derived1, typename Derived2> struct hstack_return { typedef typename Derived1::Scalar Scalar; enum { RowsAtCompileTime = Derived1::RowsAtCompileTime, - ColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::ColsAtCompileTime, Derived2::ColsAtCompileTime), + ColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::ColsAtCompileTime, + Derived2::ColsAtCompileTime), Options = Derived1::Flags&Eigen::RowMajorBit ? Eigen::RowMajor : 0, MaxRowsAtCompileTime = Derived1::MaxRowsAtCompileTime, - MaxColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxColsAtCompileTime, Derived2::MaxColsAtCompileTime) + MaxColsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxColsAtCompileTime, + Derived2::MaxColsAtCompileTime) }; typedef Eigen::Matrix<Scalar, RowsAtCompileTime, @@ -308,9 +311,10 @@ void MeanAndVarianceAlongRows(const Mat &A, }; template<typename Derived1, typename Derived2> - typename hstack_return<Derived1,Derived2>::type - HStack (const Eigen::MatrixBase<Derived1>& lhs, const Eigen::MatrixBase<Derived2>& rhs) { - typename hstack_return<Derived1,Derived2>::type res; + typename hstack_return<Derived1, Derived2>::type + HStack(const Eigen::MatrixBase<Derived1>& lhs, + const Eigen::MatrixBase<Derived2>& rhs) { + typename hstack_return<Derived1, Derived2>::type res; res.resize(lhs.rows(), lhs.cols()+rhs.cols()); res << lhs, rhs; return res; @@ -321,10 +325,12 @@ void MeanAndVarianceAlongRows(const Mat &A, struct vstack_return { typedef typename Derived1::Scalar Scalar; enum { - RowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::RowsAtCompileTime, Derived2::RowsAtCompileTime), + RowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::RowsAtCompileTime, + Derived2::RowsAtCompileTime), ColsAtCompileTime = Derived1::ColsAtCompileTime, Options = Derived1::Flags&Eigen::RowMajorBit ? Eigen::RowMajor : 0, - MaxRowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxRowsAtCompileTime, Derived2::MaxRowsAtCompileTime), + MaxRowsAtCompileTime = SUM_OR_DYNAMIC(Derived1::MaxRowsAtCompileTime, + Derived2::MaxRowsAtCompileTime), MaxColsAtCompileTime = Derived1::MaxColsAtCompileTime }; typedef Eigen::Matrix<Scalar, @@ -336,16 +342,17 @@ void MeanAndVarianceAlongRows(const Mat &A, }; template<typename Derived1, typename Derived2> - typename vstack_return<Derived1,Derived2>::type - VStack (const Eigen::MatrixBase<Derived1>& lhs, const Eigen::MatrixBase<Derived2>& rhs) { - typename vstack_return<Derived1,Derived2>::type res; + typename vstack_return<Derived1, Derived2>::type + VStack(const Eigen::MatrixBase<Derived1>& lhs, + const Eigen::MatrixBase<Derived2>& rhs) { + typename vstack_return<Derived1, Derived2>::type res; res.resize(lhs.rows()+rhs.rows(), lhs.cols()); res << lhs, rhs; return res; }; -#else //_WIN32 +#else // _WIN32 // Since it is not possible to typedef privately here, use a macro. // Always take dynamic columns if either side is dynamic. @@ -400,7 +407,7 @@ void MeanAndVarianceAlongRows(const Mat &A, } #undef COLS #undef ROWS -#endif //_WIN32 +#endif // _WIN32 @@ -454,7 +461,7 @@ inline bool isnan(double i) { /// and negative values template <typename FloatType> FloatType ceil0(const FloatType& value) { - FloatType result = std::ceil( std::fabs( value ) ); + FloatType result = std::ceil(std::fabs(value)); return (value < 0.0) ? -result : result; } @@ -470,8 +477,8 @@ inline Mat3 SkewMat(const Vec3 &x) { /// the first two (independent) lines inline Mat23 SkewMatMinimal(const Vec2 &x) { Mat23 skew; - skew << 0,-1, x(1), - 1, 0, -x(0); + skew << 0, -1, x(1), + 1, 0, -x(0); return skew; } @@ -485,6 +492,6 @@ inline Mat3 RotationFromEulerVector(Vec3 euler_vector) { Mat3 w_hat = CrossProductMatrix(w); return Mat3::Identity() + w_hat*sin(theta) + w_hat*w_hat*(1 - cos(theta)); } -} // namespace libmv +} // namespace libmv #endif // LIBMV_NUMERIC_NUMERIC_H diff --git a/extern/libmv/libmv/numeric/poly.cc b/extern/libmv/libmv/numeric/poly.cc index d96e3c104c7..376403616c3 100644 --- a/extern/libmv/libmv/numeric/poly.cc +++ b/extern/libmv/libmv/numeric/poly.cc @@ -1,15 +1,15 @@ // 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 diff --git a/extern/libmv/libmv/numeric/poly.h b/extern/libmv/libmv/numeric/poly.h index cb1d65b32c4..76ba062d475 100644 --- a/extern/libmv/libmv/numeric/poly.h +++ b/extern/libmv/libmv/numeric/poly.h @@ -1,15 +1,15 @@ // 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 @@ -36,7 +36,7 @@ namespace libmv { // // The GSL cubic solver was used as a reference for this routine. template<typename Real> -int SolveCubicPolynomial(Real a, Real b, Real c, +int SolveCubicPolynomial(Real a, Real b, Real c, Real *x0, Real *x1, Real *x2) { Real q = a * a - 3 * b; Real r = 2 * a * a * a - 9 * a * b + 27 * c; @@ -52,7 +52,7 @@ int SolveCubicPolynomial(Real a, Real b, Real c, if (R == 0 && Q == 0) { // Tripple root in one place. - *x0 = *x1 = *x2 = -a / 3 ; + *x0 = *x1 = *x2 = -a / 3; return 3; } else if (CR2 == CQ3) { @@ -62,7 +62,7 @@ int SolveCubicPolynomial(Real a, Real b, Real c, // Due to finite precision some double roots may be missed, and considered // to be a pair of complex roots z = x +/- epsilon i close to the real // axis. - Real sqrtQ = sqrt (Q); + Real sqrtQ = sqrt(Q); if (R > 0) { *x0 = -2 * sqrtQ - a / 3; *x1 = sqrtQ - a / 3; @@ -76,13 +76,13 @@ int SolveCubicPolynomial(Real a, Real b, Real c, } else if (CR2 < CQ3) { // This case is equivalent to R2 < Q3. - Real sqrtQ = sqrt (Q); + Real sqrtQ = sqrt(Q); Real sqrtQ3 = sqrtQ * sqrtQ * sqrtQ; - Real theta = acos (R / sqrtQ3); + Real theta = acos(R / sqrtQ3); Real norm = -2 * sqrtQ; - *x0 = norm * cos (theta / 3) - a / 3; - *x1 = norm * cos ((theta + 2.0 * M_PI) / 3) - a / 3; - *x2 = norm * cos ((theta - 2.0 * M_PI) / 3) - a / 3; + *x0 = norm * cos(theta / 3) - a / 3; + *x1 = norm * cos((theta + 2.0 * M_PI) / 3) - a / 3; + *x2 = norm * cos((theta - 2.0 * M_PI) / 3) - a / 3; // Put the roots in ascending order. if (*x0 > *x1) { @@ -95,10 +95,10 @@ int SolveCubicPolynomial(Real a, Real b, Real c, } } return 3; - } + } Real sgnR = (R >= 0 ? 1 : -1); - Real A = -sgnR * pow (fabs (R) + sqrt (R2 - Q3), 1.0/3.0); - Real B = Q / A ; + Real A = -sgnR * pow(fabs(R) + sqrt(R2 - Q3), 1.0/3.0); + Real B = Q / A; *x0 = A + B - a / 3; return 1; } diff --git a/extern/libmv/libmv/simple_pipeline/bundle.cc b/extern/libmv/libmv/simple_pipeline/bundle.cc index 3e36a78c9df..d84f7eb8215 100644 --- a/extern/libmv/libmv/simple_pipeline/bundle.cc +++ b/extern/libmv/libmv/simple_pipeline/bundle.cc @@ -1,15 +1,15 @@ // Copyright (c) 2011, 2012, 2013 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 @@ -18,6 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/simple_pipeline/bundle.h" + #include <map> #include "ceres/ceres.h" @@ -29,7 +31,6 @@ #include "libmv/multiview/projection.h" #include "libmv/numeric/numeric.h" #include "libmv/simple_pipeline/camera_intrinsics.h" -#include "libmv/simple_pipeline/bundle.h" #include "libmv/simple_pipeline/reconstruction.h" #include "libmv/simple_pipeline/tracks.h" @@ -125,8 +126,8 @@ struct OpenCVReprojectionError { // single parameter block. struct RotationMatrixPlus { template<typename T> - bool operator()(const T* R_array, // Rotation 3x3 col-major. - const T* delta, // Angle-axis delta + bool operator()(const T* R_array, // Rotation 3x3 col-major. + const T* delta, // Angle-axis delta T* R_plus_delta_array) const { T angle_axis[3]; @@ -293,7 +294,7 @@ void EuclideanBundleCommonIntrinsics(const Tracks &tracks, } LG << "Number of residuals: " << num_residuals; - if(!num_residuals) { + if (!num_residuals) { LG << "Skipping running minimizer with zero residuals"; return; } diff --git a/extern/libmv/libmv/simple_pipeline/bundle.h b/extern/libmv/libmv/simple_pipeline/bundle.h index 573bcf4cc21..6235b46f1e7 100644 --- a/extern/libmv/libmv/simple_pipeline/bundle.h +++ b/extern/libmv/libmv/simple_pipeline/bundle.h @@ -1,15 +1,15 @@ // Copyright (c) 2011 libmv authors. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -89,14 +89,15 @@ enum BundleIntrinsics { BUNDLE_TANGENTIAL = 48, }; enum BundleConstraints { - BUNDLE_NO_CONSTRAINTS = 0, - BUNDLE_NO_TRANSLATION = 1, + BUNDLE_NO_CONSTRAINTS = 0, + BUNDLE_NO_TRANSLATION = 1, }; void EuclideanBundleCommonIntrinsics(const Tracks &tracks, int bundle_intrinsics, EuclideanReconstruction *reconstruction, CameraIntrinsics *intrinsics, - int bundle_constraints = BUNDLE_NO_CONSTRAINTS); + int bundle_constraints = + BUNDLE_NO_CONSTRAINTS); /*! Refine camera poses and 3D coordinates using bundle adjustment. diff --git a/extern/libmv/libmv/simple_pipeline/callbacks.cc b/extern/libmv/libmv/simple_pipeline/callbacks.cc deleted file mode 100644 index 7e4bca6efc7..00000000000 --- a/extern/libmv/libmv/simple_pipeline/callbacks.cc +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2011 libmv authors. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to -// deal in the Software without restriction, including without limitation the -// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -// sell copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. - -#include "libmv/simple_pipeline/callbacks.h" - -namespace libmv { - -void ProgressUpdateCallback::invoke(double progress, const char* message) -{ -} - -} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/callbacks.h b/extern/libmv/libmv/simple_pipeline/callbacks.h index 675f73c1cab..58f7b0d3cc9 100644 --- a/extern/libmv/libmv/simple_pipeline/callbacks.h +++ b/extern/libmv/libmv/simple_pipeline/callbacks.h @@ -25,7 +25,8 @@ namespace libmv { class ProgressUpdateCallback { public: - virtual void invoke(double progress, const char *message); + virtual ~ProgressUpdateCallback() {} + virtual void invoke(double progress, const char *message) = 0; }; } // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc index 543fddedd0c..aee2ecb5882 100644 --- a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc +++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.cc @@ -25,7 +25,7 @@ namespace libmv { struct Offset { short ix, iy; - unsigned char fx,fy; + unsigned char fx, fy; }; struct Grid { @@ -34,8 +34,7 @@ struct Grid { double overscan; }; -static struct Grid *copyGrid(struct Grid *from) -{ +static struct Grid *copyGrid(struct Grid *from) { struct Grid *to = NULL; if (from) { @@ -74,8 +73,7 @@ CameraIntrinsics::CameraIntrinsics(const CameraIntrinsics &from) k3_(from.k3_), p1_(from.p1_), p2_(from.p2_), - threads_(from.threads_) -{ + threads_(from.threads_) { distort_ = copyGrid(from.distort_); undistort_ = copyGrid(from.undistort_); } @@ -122,9 +120,8 @@ void CameraIntrinsics::SetTangentialDistortion(double p1, double p2) { FreeLookupGrid(); } -void CameraIntrinsics::SetThreads(int threads) -{ - threads_ = threads; +void CameraIntrinsics::SetThreads(int threads) { + threads_ = threads; } void CameraIntrinsics::ApplyIntrinsics(double normalized_x, @@ -189,68 +186,76 @@ void CameraIntrinsics::InvertIntrinsics(double image_x, // TODO(MatthiasF): downsample lookup template<typename WarpFunction> -void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height, double overscan) { +void CameraIntrinsics::ComputeLookupGrid(Grid* grid, int width, int height, + double overscan) { double w = (double)width / (1 + overscan); double h = (double)height / (1 + overscan); double aspx = (double)w / image_width_; double aspy = (double)h / image_height_; - +#if defined(_OPENMP) #pragma omp parallel for schedule(dynamic) num_threads(threads_) if (threads_ > 1 && height > 100) +#endif for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { - double src_x = (x - 0.5 * overscan * w) / aspx, src_y = (y - 0.5 * overscan * h) / aspy; + double src_x = (x - 0.5 * overscan * w) / aspx, + src_y = (y - 0.5 * overscan * h) / aspy; double warp_x, warp_y; - WarpFunction(this,src_x,src_y,&warp_x,&warp_y); + WarpFunction(this, src_x, src_y, &warp_x, &warp_y); warp_x = warp_x*aspx + 0.5 * overscan * w; warp_y = warp_y*aspy + 0.5 * overscan * h; int ix = int(warp_x), iy = int(warp_y); int fx = round((warp_x-ix)*256), fy = round((warp_y-iy)*256); - if(fx == 256) { fx=0; ix++; } - if(fy == 256) { fy=0; iy++; } + if (fx == 256) { fx = 0; ix++; } // NOLINT + if (fy == 256) { fy = 0; iy++; } // NOLINT // Use nearest border pixel - if( ix < 0 ) { ix = 0, fx = 0; } - if( iy < 0 ) { iy = 0, fy = 0; } - if( ix >= width-2 ) ix = width-2; - if( iy >= height-2 ) iy = height-2; + if (ix < 0) { ix = 0, fx = 0; } // NOLINT + if (iy < 0) { iy = 0, fy = 0; } // NOLINT + if (ix >= width - 2) ix = width-2; + if (iy >= height - 2) iy = height-2; - Offset offset = { (short)(ix-x), (short)(iy-y), (unsigned char)fx, (unsigned char)fy }; + Offset offset = { (short)(ix-x), (short)(iy-y), + (unsigned char)fx, (unsigned char)fy }; grid->offset[y*width+x] = offset; } } } // TODO(MatthiasF): cubic B-Spline image sampling, bilinear lookup -template<typename T,int N> +template<typename T, int N> static void Warp(const Grid* grid, const T* src, T* dst, int width, int height, int threads) { + (void) threads; // Ignored if OpenMP is disabled +#if defined(_OPENMP) #pragma omp parallel for schedule(dynamic) num_threads(threads) if (threads > 1 && height > 100) +#endif for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { Offset offset = grid->offset[y*width+x]; const T* s = &src[((y+offset.iy)*width+(x+offset.ix))*N]; for (int i = 0; i < N; i++) { - dst[(y*width+x)*N+i] = ((s[ i] * (256-offset.fx) + s[ N+i] * offset.fx) * (256-offset.fy) - +(s[width*N+i] * (256-offset.fx) + s[width*N+N+i] * offset.fx) * offset.fy) / (256*256); + dst[(y*width+x)*N+i] = ((s[ i] * (256-offset.fx) + s[ N+i] * offset.fx) * (256-offset.fy) // NOLINT + +(s[width*N+i] * (256-offset.fx) + s[width*N+N+i] * offset.fx) * offset.fy) / (256*256); // NOLINT } } } } void CameraIntrinsics::FreeLookupGrid() { - if(distort_) { + if (distort_) { delete distort_->offset; delete distort_; distort_ = NULL; } - if(undistort_) { + if (undistort_) { delete undistort_->offset; delete undistort_; undistort_ = NULL; } } -// FIXME: C++ templates limitations makes thing complicated, but maybe there is a simpler method. +// FIXME: C++ templates limitations makes thing complicated, +// but maybe there is a simpler method. struct ApplyIntrinsicsFunction { ApplyIntrinsicsFunction(CameraIntrinsics* intrinsics, double x, double y, double *warp_x, double *warp_y) { @@ -263,16 +268,21 @@ struct ApplyIntrinsicsFunction { struct InvertIntrinsicsFunction { InvertIntrinsicsFunction(CameraIntrinsics* intrinsics, double x, double y, double *warp_x, double *warp_y) { - intrinsics->InvertIntrinsics(x,y,warp_x,warp_y); - *warp_x = *warp_x*intrinsics->focal_length_x()+intrinsics->principal_point_x(); - *warp_y = *warp_y*intrinsics->focal_length_y()+intrinsics->principal_point_y(); + intrinsics->InvertIntrinsics(x, y, warp_x, warp_y); + + *warp_x = *warp_x * intrinsics->focal_length_x() + + intrinsics->principal_point_x(); + + *warp_y = *warp_y * intrinsics->focal_length_y() + + intrinsics->principal_point_y(); } }; -void CameraIntrinsics::CheckDistortLookupGrid(int width, int height, double overscan) -{ - if(distort_) { - if(distort_->width != width || distort_->height != height || distort_->overscan != overscan) { +void CameraIntrinsics::CheckDistortLookupGrid(int width, int height, + double overscan) { + if (distort_) { + if (distort_->width != width || distort_->height != height || + distort_->overscan != overscan) { delete [] distort_->offset; distort_->offset = NULL; } @@ -281,9 +291,10 @@ void CameraIntrinsics::CheckDistortLookupGrid(int width, int height, double over distort_->offset = NULL; } - if(!distort_->offset) { - distort_->offset = new Offset[width*height]; - ComputeLookupGrid<InvertIntrinsicsFunction>(distort_,width,height,overscan); + if (!distort_->offset) { + distort_->offset = new Offset[width * height]; + ComputeLookupGrid<InvertIntrinsicsFunction>(distort_, width, + height, overscan); } distort_->width = width; @@ -291,10 +302,11 @@ void CameraIntrinsics::CheckDistortLookupGrid(int width, int height, double over distort_->overscan = overscan; } -void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height, double overscan) -{ - if(undistort_) { - if(undistort_->width != width || undistort_->height != height || undistort_->overscan != overscan) { +void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height, + double overscan) { + if (undistort_) { + if (undistort_->width != width || undistort_->height != height || + undistort_->overscan != overscan) { delete [] undistort_->offset; undistort_->offset = NULL; } @@ -303,9 +315,10 @@ void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height, double ov undistort_->offset = NULL; } - if(!undistort_->offset) { - undistort_->offset = new Offset[width*height]; - ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_,width,height,overscan); + if (!undistort_->offset) { + undistort_->offset = new Offset[width * height]; + ComputeLookupGrid<ApplyIntrinsicsFunction>(undistort_, width, + height, overscan); } undistort_->width = width; @@ -313,39 +326,53 @@ void CameraIntrinsics::CheckUndistortLookupGrid(int width, int height, double ov undistort_->overscan = overscan; } -void CameraIntrinsics::Distort(const float* src, float* dst, int width, int height, double overscan, int channels) { +void CameraIntrinsics::Distort(const float* src, float* dst, + int width, int height, + double overscan, + int channels) { CheckDistortLookupGrid(width, height, overscan); - if(channels==1) Warp<float,1>(distort_,src,dst,width,height,threads_); - else if(channels==2) Warp<float,2>(distort_,src,dst,width,height,threads_); - else if(channels==3) Warp<float,3>(distort_,src,dst,width,height,threads_); - else if(channels==4) Warp<float,4>(distort_,src,dst,width,height,threads_); + if (channels==1) Warp<float,1>(distort_, src, dst, width, height, threads_); // NOLINT + else if (channels==2) Warp<float,2>(distort_, src, dst, width, height, threads_); // NOLINT + else if (channels==3) Warp<float,3>(distort_, src, dst, width, height, threads_); // NOLINT + else if (channels==4) Warp<float,4>(distort_, src, dst, width, height, threads_); // NOLINT //else assert("channels must be between 1 and 4"); } -void CameraIntrinsics::Distort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) { +void CameraIntrinsics::Distort(const unsigned char* src, + unsigned char* dst, + int width, int height, + double overscan, + int channels) { CheckDistortLookupGrid(width, height, overscan); - if(channels==1) Warp<unsigned char,1>(distort_,src,dst,width,height,threads_); - else if(channels==2) Warp<unsigned char,2>(distort_,src,dst,width,height,threads_); - else if(channels==3) Warp<unsigned char,3>(distort_,src,dst,width,height,threads_); - else if(channels==4) Warp<unsigned char,4>(distort_,src,dst,width,height,threads_); + if (channels == 1) Warp<unsigned char,1>(distort_, src, dst, width, height, threads_); // NOLINT + else if (channels == 2) Warp<unsigned char,2>(distort_, src, dst, width, height, threads_); // NOLINT + else if (channels == 3) Warp<unsigned char,3>(distort_, src, dst, width, height, threads_); // NOLINT + else if (channels == 4) Warp<unsigned char,4>(distort_, src, dst, width, height, threads_); // NOLINT //else assert("channels must be between 1 and 4"); } -void CameraIntrinsics::Undistort(const float* src, float* dst, int width, int height, double overscan, int channels) { +void CameraIntrinsics::Undistort(const float* src, float* dst, + int width, int height, + double overscan, + int channels) { CheckUndistortLookupGrid(width, height, overscan); - if(channels==1) Warp<float,1>(undistort_,src,dst,width,height,threads_); - else if(channels==2) Warp<float,2>(undistort_,src,dst,width,height,threads_); - else if(channels==3) Warp<float,3>(undistort_,src,dst,width,height,threads_); - else if(channels==4) Warp<float,4>(undistort_,src,dst,width,height,threads_); + if (channels == 1) Warp<float,1>(undistort_, src, dst, width, height, threads_); // NOLINT + else if (channels == 2) Warp<float,2>(undistort_, src, dst, width, height, threads_); // NOLINT + else if (channels == 3) Warp<float,3>(undistort_, src, dst, width, height, threads_); // NOLINT + else if (channels == 4) Warp<float,4>(undistort_, src, dst, width, height, threads_); // NOLINT //else assert("channels must be between 1 and 4"); } -void CameraIntrinsics::Undistort(const unsigned char* src, unsigned char* dst, int width, int height, double overscan, int channels) { +void CameraIntrinsics::Undistort(const unsigned char* src, + unsigned char* dst, + int width, int height, + double overscan, + int channels) { CheckUndistortLookupGrid(width, height, overscan); - if(channels==1) Warp<unsigned char,1>(undistort_,src,dst,width,height,threads_); - else if(channels==2) Warp<unsigned char,2>(undistort_,src,dst,width,height,threads_); - else if(channels==3) Warp<unsigned char,3>(undistort_,src,dst,width,height,threads_); - else if(channels==4) Warp<unsigned char,4>(undistort_,src,dst,width,height,threads_); + if (channels == 1) Warp<unsigned char,1>(undistort_, src, dst, width, height, threads_); // NOLINT + else if (channels == 2) Warp<unsigned char,2>(undistort_, src, dst, width, height, threads_); // NOLINT + else if (channels == 3) Warp<unsigned char,3>(undistort_, src, dst, width, height, threads_); // NOLINT + else if (channels == 4) Warp<unsigned char,4>(undistort_, src, dst, width, height, threads_); // NOLINT //else assert("channels must be between 1 and 4"); } diff --git a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h index 632922c38ff..29d26c7f9ab 100644 --- a/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h +++ b/extern/libmv/libmv/simple_pipeline/camera_intrinsics.h @@ -135,7 +135,10 @@ class CameraIntrinsics { int width, int height, double overscan, int channels); private: - template<typename WarpFunction> void ComputeLookupGrid(struct Grid* grid, int width, int height, double overscan); + template<typename WarpFunction> void ComputeLookupGrid(struct Grid* grid, + int width, + int height, + double overscan); void CheckUndistortLookupGrid(int width, int height, double overscan); void CheckDistortLookupGrid(int width, int height, double overscan); void FreeLookupGrid(); diff --git a/extern/libmv/libmv/simple_pipeline/detect.cc b/extern/libmv/libmv/simple_pipeline/detect.cc index 9e3edf32d71..8451e47d374 100644 --- a/extern/libmv/libmv/simple_pipeline/detect.cc +++ b/extern/libmv/libmv/simple_pipeline/detect.cc @@ -35,37 +35,40 @@ namespace libmv { typedef unsigned int uint; -static int featurecmp(const void *a_v, const void *b_v) -{ +static int featurecmp(const void *a_v, const void *b_v) { Feature *a = (Feature*)a_v; Feature *b = (Feature*)b_v; return b->score - a->score; } -std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height, int stride, - int min_trackness, int min_distance) { +std::vector<Feature> DetectFAST(const unsigned char* data, + int width, int height, + int stride, + int min_trackness, + int min_distance) { std::vector<Feature> features; // TODO(MatthiasF): Support targetting a feature count (binary search trackness) int num_features; xy* all = fast9_detect(data, width, height, stride, min_trackness, &num_features); - if(num_features == 0) { + if (num_features == 0) { free(all); return features; } int* scores = fast9_score(data, stride, all, num_features, min_trackness); - // TODO: merge with close feature suppression + // TODO(MatthiasF): merge with close feature suppression xy* nonmax = nonmax_suppression(all, scores, num_features, &num_features); free(all); // Remove too close features - // TODO(MatthiasF): A resolution independent parameter would be better than distance - // e.g. a coefficient going from 0 (no minimal distance) to 1 (optimal circle packing) + // TODO(MatthiasF): A resolution independent parameter would be better than + // distance e.g. a coefficient going from 0 (no minimal distance) to 1 + // (optimal circle packing) // FIXME(MatthiasF): this method will not necessarily give all maximum markers - if(num_features) { + if (num_features) { Feature *all_features = new Feature[num_features]; - for(int i = 0; i < num_features; ++i) { + for (int i = 0; i < num_features; ++i) { Feature a = { (float)nonmax[i].x, (float)nonmax[i].y, (float)scores[i], 0 }; all_features[i] = a; } @@ -75,15 +78,15 @@ std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height features.reserve(num_features); int prev_score = all_features[0].score; - for(int i = 0; i < num_features; ++i) { + for (int i = 0; i < num_features; ++i) { bool ok = true; Feature a = all_features[i]; - if(a.score>prev_score) + if (a.score>prev_score) abort(); prev_score = a.score; // compare each feature against filtered set - for(int j = 0; j < features.size(); j++) { + for (int j = 0; j < features.size(); j++) { Feature& b = features[j]; if ( (a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y) < min_distance*min_distance ) { // already a nearby feature @@ -92,7 +95,7 @@ std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height } } - if(ok) { + if (ok) { // add the new feature features.push_back(a); } @@ -106,19 +109,22 @@ std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height } #ifdef __SSE2__ -static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) { +static uint SAD(const ubyte* imageA, const ubyte* imageB, + int strideA, int strideB) { __m128i a = _mm_setzero_si128(); - for(int i = 0; i < 16; i++) { - a = _mm_adds_epu16(a, _mm_sad_epu8( _mm_loadu_si128((__m128i*)(imageA+i*strideA)), - _mm_loadu_si128((__m128i*)(imageB+i*strideB)))); + for (int i = 0; i < 16; i++) { + a = _mm_adds_epu16(a, + _mm_sad_epu8(_mm_loadu_si128((__m128i*)(imageA+i*strideA)), + _mm_loadu_si128((__m128i*)(imageB+i*strideB)))); } - return _mm_extract_epi16(a,0) + _mm_extract_epi16(a,4); + return _mm_extract_epi16(a, 0) + _mm_extract_epi16(a, 4); } #else -static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strideB) { - uint sad=0; - for(int i = 0; i < 16; i++) { - for(int j = 0; j < 16; j++) { +static uint SAD(const ubyte* imageA, const ubyte* imageB, + int strideA, int strideB) { + uint sad = 0; + for (int i = 0; i < 16; i++) { + for (int j = 0; j < 16; j++) { sad += abs((int)imageA[i*strideA+j] - imageB[i*strideB+j]); } } @@ -126,59 +132,68 @@ static uint SAD(const ubyte* imageA, const ubyte* imageB, int strideA, int strid } #endif -void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance, ubyte* pattern) { +void DetectMORAVEC(ubyte* image, + int stride, int width, int height, + Feature* detected, int* count, + int distance, + ubyte* pattern) { unsigned short histogram[256]; - memset(histogram,0,sizeof(histogram)); + memset(histogram, 0, sizeof(histogram)); ubyte* scores = new ubyte[width*height]; - memset(scores,0,width*height); - const int r = 1; //radius for self similarity comparison - for(int y=distance; y<height-distance; y++) { - for(int x=distance; x<width-distance; x++) { + memset(scores, 0, width*height); + const int r = 1; // radius for self similarity comparison + for (int y = distance; y < height-distance; y++) { + for (int x = distance; x < width-distance; x++) { ubyte* s = &image[y*stride+x]; - int score = // low self-similarity with overlapping patterns //OPTI: load pattern once + int score = // low self-similarity with overlapping patterns + // OPTI: load pattern once SAD(s, s-r*stride-r, stride, stride)+SAD(s, s-r*stride, stride, stride)+SAD(s, s-r*stride+r, stride, stride)+ SAD(s, s -r, stride, stride)+ SAD(s, s +r, stride, stride)+ SAD(s, s+r*stride-r, stride, stride)+SAD(s, s+r*stride, stride, stride)+SAD(s, s+r*stride+r, stride, stride); - score /= 256; // normalize - if(pattern) score -= SAD(s, pattern, stride, 16); // find only features similar to pattern - if(score<=16) continue; // filter very self-similar features - score -= 16; // translate to score/histogram values - if(score>255) score=255; // clip + score /= 256; // normalize + if (pattern) // find only features similar to pattern + score -= SAD(s, pattern, stride, 16); + if (score <= 16) continue; // filter very self-similar features + score -= 16; // translate to score/histogram values + if (score>255) score=255; // clip ubyte* c = &scores[y*width+x]; - for(int i=-distance; i<0; i++) { - for(int j=-distance; j<distance; j++) { + for (int i = -distance; i < 0; i++) { + for (int j = -distance; j < distance; j++) { int s = c[i*width+j]; - if(s == 0) continue; - if(s >= score) goto nonmax; - c[i*width+j]=0, histogram[s]--; + if (s == 0) continue; + if (s >= score) goto nonmax; + c[i*width+j] = 0; + histogram[s]--; } } - for(int i=0, j=-distance; j<0; j++) { + for (int i = 0, j = -distance; j < 0; j++) { int s = c[i*width+j]; - if(s == 0) continue; - if(s >= score) goto nonmax; - c[i*width+j]=0, histogram[s]--; + if (s == 0) continue; + if (s >= score) goto nonmax; + c[i*width+j] = 0; + histogram[s]--; } c[0] = score, histogram[score]++; - nonmax:; + nonmax: + { } // Do nothing. } } - int min=255, total=0; - for(; min>0; min--) { + int min = 255, total = 0; + for (; min > 0; min--) { int h = histogram[min]; - if(total+h > *count) break; + if (total+h > *count) break; total += h; } - int i=0; - for(int y=16; y<height-16; y++) { - for(int x=16; x<width-16; x++) { + int i = 0; + for (int y = 16; y < height-16; y++) { + for (int x = 16; x < width-16; x++) { int s = scores[y*width+x]; Feature f = { (float)x+8.0f, (float)y+8.0f, (float)s, 16 }; - if(s>min) detected[i++] = f; + if (s > min) detected[i++] = f; } } *count = i; delete[] scores; } -} +} // namespace libmv diff --git a/extern/libmv/libmv/simple_pipeline/detect.h b/extern/libmv/libmv/simple_pipeline/detect.h index bbe7aed784c..6d0f55a082f 100644 --- a/extern/libmv/libmv/simple_pipeline/detect.h +++ b/extern/libmv/libmv/simple_pipeline/detect.h @@ -88,8 +88,10 @@ std::vector<Feature> DetectFAST(const unsigned char* data, int width, int height \note \a You can crop the image (to avoid detecting markers near the borders) without copying: image += marginY*stride+marginX, width -= 2*marginX, height -= 2*marginY; */ -void DetectMORAVEC(ubyte* image, int stride, int width, int height, Feature* detected, int* count, int distance /*=32*/, ubyte* pattern /*=0*/); +void DetectMORAVEC(ubyte* image, int stride, int width, int height, + Feature* detected, int* count, int distance /*=32*/, + ubyte* pattern /*=0*/); -} +} // namespace libmv #endif diff --git a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc index 84d143b77d6..246828a644f 100644 --- a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc +++ b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.cc @@ -1,15 +1,15 @@ // Copyright (c) 2011 libmv authors. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -18,13 +18,14 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/simple_pipeline/initialize_reconstruction.h" + #include "libmv/base/vector.h" #include "libmv/logging/logging.h" #include "libmv/multiview/fundamental.h" #include "libmv/multiview/projection.h" #include "libmv/numeric/levenberg_marquardt.h" #include "libmv/numeric/numeric.h" -#include "libmv/simple_pipeline/initialize_reconstruction.h" #include "libmv/simple_pipeline/reconstruction.h" #include "libmv/simple_pipeline/tracks.h" @@ -109,7 +110,8 @@ namespace { Mat3 DecodeF(const Vec9 &encoded_F) { // Decode F and force it to be rank 2. Map<const Mat3> full_rank_F(encoded_F.data(), 3, 3); - Eigen::JacobiSVD<Mat3> svd(full_rank_F, Eigen::ComputeFullU | Eigen::ComputeFullV); + Eigen::JacobiSVD<Mat3> svd(full_rank_F, + Eigen::ComputeFullU | Eigen::ComputeFullV); Vec3 diagonal = svd.singularValues(); diagonal(2) = 0; Mat3 F = svd.matrixU() * diagonal.asDiagonal() * svd.matrixV().transpose(); @@ -130,7 +132,7 @@ struct FundamentalSampsonCostFunction { Vec operator()(const Vec9 &encoded_F) const { // Decode F and force it to be rank 2. Mat3 F = DecodeF(encoded_F); - + Vec residuals(markers.size() / 2); residuals.setZero(); for (int i = 0; i < markers.size() / 2; ++i) { diff --git a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h index f512c9a3439..744436246b0 100644 --- a/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h +++ b/extern/libmv/libmv/simple_pipeline/initialize_reconstruction.h @@ -1,15 +1,15 @@ // Copyright (c) 2011 libmv authors. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/extern/libmv/libmv/simple_pipeline/intersect.cc b/extern/libmv/libmv/simple_pipeline/intersect.cc index d0f139a991a..d2dde4b36af 100644 --- a/extern/libmv/libmv/simple_pipeline/intersect.cc +++ b/extern/libmv/libmv/simple_pipeline/intersect.cc @@ -1,15 +1,15 @@ // Copyright (c) 2011 libmv authors. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -25,7 +25,6 @@ #include "libmv/multiview/projection.h" #include "libmv/multiview/triangulation.h" #include "libmv/multiview/nviewtriangulation.h" -#include "libmv/multiview/projection.h" #include "libmv/numeric/numeric.h" #include "libmv/numeric/levenberg_marquardt.h" #include "libmv/simple_pipeline/reconstruction.h" diff --git a/extern/libmv/libmv/simple_pipeline/intersect.h b/extern/libmv/libmv/simple_pipeline/intersect.h index edbf4a0335b..3a0ffa7418b 100644 --- a/extern/libmv/libmv/simple_pipeline/intersect.h +++ b/extern/libmv/libmv/simple_pipeline/intersect.h @@ -1,15 +1,15 @@ // Copyright (c) 2011 libmv authors. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/extern/libmv/libmv/simple_pipeline/modal_solver.cc b/extern/libmv/libmv/simple_pipeline/modal_solver.cc index d79c71508cc..90dfde15660 100644 --- a/extern/libmv/libmv/simple_pipeline/modal_solver.cc +++ b/extern/libmv/libmv/simple_pipeline/modal_solver.cc @@ -34,7 +34,7 @@ namespace libmv { namespace { -void ProjectMarkerOnSphere(Marker &marker, Vec3 &X) { +void ProjectMarkerOnSphere(const Marker &marker, Vec3 &X) { X(0) = marker.x; X(1) = marker.y; X(2) = 1.0; @@ -43,8 +43,7 @@ void ProjectMarkerOnSphere(Marker &marker, Vec3 &X) { } void ModalSolverLogProress(ProgressUpdateCallback *update_callback, - double progress) -{ + double progress) { if (update_callback) { char message[256]; @@ -56,13 +55,14 @@ void ModalSolverLogProress(ProgressUpdateCallback *update_callback, } struct ModalReprojectionError { - ModalReprojectionError(double observed_x, double observed_y, Vec3 &bundle) + ModalReprojectionError(double observed_x, + double observed_y, + const Vec3 &bundle) : observed_x(observed_x), observed_y(observed_y), bundle(bundle) { } template <typename T> bool operator()(const T* quaternion, // Rotation quaternion T* residuals) const { - T R[9]; ceres::QuaternionToRotation(quaternion, R); @@ -96,7 +96,7 @@ struct ModalReprojectionError { }; } // namespace -void ModalSolver(Tracks &tracks, +void ModalSolver(const Tracks &tracks, EuclideanReconstruction *reconstruction, ProgressUpdateCallback *update_callback) { int max_image = tracks.MaxImage(); diff --git a/extern/libmv/libmv/simple_pipeline/modal_solver.h b/extern/libmv/libmv/simple_pipeline/modal_solver.h index 560b37c2987..9801fd21d81 100644 --- a/extern/libmv/libmv/simple_pipeline/modal_solver.h +++ b/extern/libmv/libmv/simple_pipeline/modal_solver.h @@ -39,7 +39,7 @@ namespace libmv { Reconstructed cameras and projected bundles would be added to reconstruction object. */ -void ModalSolver(Tracks &tracks, +void ModalSolver(const Tracks &tracks, EuclideanReconstruction *reconstruction, ProgressUpdateCallback *update_callback = NULL); diff --git a/extern/libmv/libmv/simple_pipeline/pipeline.cc b/extern/libmv/libmv/simple_pipeline/pipeline.cc index 463738e42bb..f6013d71867 100644 --- a/extern/libmv/libmv/simple_pipeline/pipeline.cc +++ b/extern/libmv/libmv/simple_pipeline/pipeline.cc @@ -18,10 +18,11 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/simple_pipeline/pipeline.h" + #include <cstdio> #include "libmv/logging/logging.h" -#include "libmv/simple_pipeline/pipeline.h" #include "libmv/simple_pipeline/bundle.h" #include "libmv/simple_pipeline/intersect.h" #include "libmv/simple_pipeline/resect.h" @@ -92,6 +93,9 @@ struct ProjectivePipelineRoutines { static bool Resect(const ReconstructionOptions &options, const vector<Marker> &markers, ProjectiveReconstruction *reconstruction, bool final_pass) { + (void) options; // Ignored. + (void) final_pass; // Ignored. + return ProjectiveResect(markers, reconstruction); } @@ -120,17 +124,19 @@ struct ProjectivePipelineRoutines { } // namespace -static void CompleteReconstructionLogProress(ProgressUpdateCallback *update_callback, +static void CompleteReconstructionLogProress( + ProgressUpdateCallback *update_callback, double progress, - const char *step = NULL) -{ - if(update_callback) { + const char *step = NULL) { + if (update_callback) { char message[256]; - if(step) - snprintf(message, sizeof(message), "Completing solution %d%% | %s", (int)(progress*100), step); + if (step) + snprintf(message, sizeof(message), "Completing solution %d%% | %s", + (int)(progress*100), step); else - snprintf(message, sizeof(message), "Completing solution %d%%", (int)(progress*100)); + snprintf(message, sizeof(message), "Completing solution %d%%", + (int)(progress*100)); update_callback->invoke(progress, message); } @@ -207,7 +213,8 @@ void InternalCompleteReconstruction( if (reconstructed_markers.size() >= 5) { CompleteReconstructionLogProress(update_callback, (double)tot_resects/(max_image)); - if (PipelineRoutines::Resect(options, reconstructed_markers, reconstruction, false)) { + if (PipelineRoutines::Resect(options, reconstructed_markers, + reconstruction, false)) { num_resects++; tot_resects++; LG << "Ran Resect() for image " << image; @@ -243,7 +250,8 @@ void InternalCompleteReconstruction( if (reconstructed_markers.size() >= 5) { CompleteReconstructionLogProress(update_callback, (double)tot_resects/(max_image)); - if (PipelineRoutines::Resect(options, reconstructed_markers, reconstruction, true)) { + if (PipelineRoutines::Resect(options, reconstructed_markers, + reconstruction, true)) { num_resects++; LG << "Ran final Resect() for image " << image; } else { @@ -260,9 +268,10 @@ void InternalCompleteReconstruction( } template<typename PipelineRoutines> -double InternalReprojectionError(const Tracks &image_tracks, - const typename PipelineRoutines::Reconstruction &reconstruction, - const CameraIntrinsics &intrinsics) { +double InternalReprojectionError( + const Tracks &image_tracks, + const typename PipelineRoutines::Reconstruction &reconstruction, + const CameraIntrinsics &intrinsics) { int num_skipped = 0; int num_reprojected = 0; double total_error = 0.0; diff --git a/extern/libmv/libmv/simple_pipeline/pipeline.h b/extern/libmv/libmv/simple_pipeline/pipeline.h index 11c11297d78..d8489012b95 100644 --- a/extern/libmv/libmv/simple_pipeline/pipeline.h +++ b/extern/libmv/libmv/simple_pipeline/pipeline.h @@ -49,10 +49,11 @@ namespace libmv { \sa EuclideanResect, EuclideanIntersect, EuclideanBundle */ -void EuclideanCompleteReconstruction(const ReconstructionOptions &options, - const Tracks &tracks, - EuclideanReconstruction *reconstruction, - ProgressUpdateCallback *update_callback = NULL); +void EuclideanCompleteReconstruction( + const ReconstructionOptions &options, + const Tracks &tracks, + EuclideanReconstruction *reconstruction, + ProgressUpdateCallback *update_callback = NULL); /*! Estimate camera matrices and homogeneous 3D coordinates for all frames and diff --git a/extern/libmv/libmv/simple_pipeline/reconstruction.h b/extern/libmv/libmv/simple_pipeline/reconstruction.h index 71789e3a245..1610029b9d2 100644 --- a/extern/libmv/libmv/simple_pipeline/reconstruction.h +++ b/extern/libmv/libmv/simple_pipeline/reconstruction.h @@ -27,14 +27,14 @@ namespace libmv { struct ReconstructionOptions { - // threshold value of reconstruction error which is still considered successful - // if reconstruction error bigger than this value, fallback reconstruction - // algorithm would be used (if enabled) - double success_threshold; - - // use fallback reconstruction algorithm in cases main reconstruction algorithm - // failed to reconstruct - bool use_fallback_reconstruction; + // threshold value of reconstruction error which is still considered successful + // if reconstruction error bigger than this value, fallback reconstruction + // algorithm would be used (if enabled) + double success_threshold; + + // use fallback reconstruction algorithm in cases main reconstruction algorithm + // failed to reconstruct + bool use_fallback_reconstruction; }; /*! diff --git a/extern/libmv/libmv/simple_pipeline/resect.cc b/extern/libmv/libmv/simple_pipeline/resect.cc index 3929271e66f..941c95cf237 100644 --- a/extern/libmv/libmv/simple_pipeline/resect.cc +++ b/extern/libmv/libmv/simple_pipeline/resect.cc @@ -1,15 +1,15 @@ // Copyright (c) 2011 libmv authors. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -18,6 +18,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/simple_pipeline/resect.h" + #include <cstdio> #include "libmv/base/vector.h" @@ -27,7 +29,6 @@ #include "libmv/multiview/projection.h" #include "libmv/numeric/numeric.h" #include "libmv/numeric/levenberg_marquardt.h" -#include "libmv/simple_pipeline/resect.h" #include "libmv/simple_pipeline/reconstruction.h" #include "libmv/simple_pipeline/tracks.h" @@ -108,13 +109,13 @@ bool EuclideanResect(const ReconstructionOptions &options, double success_threshold = std::numeric_limits<double>::max(); - if(options.use_fallback_reconstruction) + if (options.use_fallback_reconstruction) success_threshold = options.success_threshold; - if (0 || !euclidean_resection::EuclideanResection(points_2d, points_3d, &R, &t, - euclidean_resection::RESECTION_EPNP, - success_threshold)) - { + if (0 || !euclidean_resection::EuclideanResection( + points_2d, points_3d, &R, &t, + euclidean_resection::RESECTION_EPNP, + success_threshold)) { // printf("Resection for image %d failed\n", markers[0].image); LG << "Resection for image " << markers[0].image << " failed;" << " trying fallback projective resection."; @@ -172,7 +173,7 @@ bool EuclideanResect(const ReconstructionOptions &options, Solver solver(resect_cost); Solver::SolverParameters params; - Solver::Results results = solver.minimize(params, &dRt); + /* Solver::Results results = */ solver.minimize(params, &dRt); LG << "LM found incremental rotation: " << dRt.head<3>().transpose(); // TODO(keir): Check results to ensure clean termination. @@ -264,7 +265,7 @@ bool ProjectiveResect(const vector<Marker> &markers, Solver solver(resect_cost); Solver::SolverParameters params; - Solver::Results results = solver.minimize(params, &vector_P); + /* Solver::Results results = */ solver.minimize(params, &vector_P); // TODO(keir): Check results to ensure clean termination. // Unpack the projection matrix. diff --git a/extern/libmv/libmv/simple_pipeline/resect.h b/extern/libmv/libmv/simple_pipeline/resect.h index 1691e7ee245..47a6c6b60ea 100644 --- a/extern/libmv/libmv/simple_pipeline/resect.h +++ b/extern/libmv/libmv/simple_pipeline/resect.h @@ -1,15 +1,15 @@ // Copyright (c) 2011 libmv authors. -// +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: -// +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. -// +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE diff --git a/extern/libmv/libmv/simple_pipeline/tracks.cc b/extern/libmv/libmv/simple_pipeline/tracks.cc index 620f6fc880a..f9e50d20af9 100644 --- a/extern/libmv/libmv/simple_pipeline/tracks.cc +++ b/extern/libmv/libmv/simple_pipeline/tracks.cc @@ -18,12 +18,13 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/simple_pipeline/tracks.h" + #include <algorithm> #include <vector> #include <iterator> #include "libmv/numeric/numeric.h" -#include "libmv/simple_pipeline/tracks.h" namespace libmv { @@ -82,7 +83,8 @@ vector<Marker> Tracks::MarkersInBothImages(int image1, int image2) const { return markers; } -vector<Marker> Tracks::MarkersForTracksInBothImages(int image1, int image2) const { +vector<Marker> Tracks::MarkersForTracksInBothImages(int image1, + int image2) const { std::vector<int> image1_tracks; std::vector<int> image2_tracks; @@ -106,7 +108,7 @@ vector<Marker> Tracks::MarkersForTracksInBothImages(int image1, int image2) cons vector<Marker> markers; for (int i = 0; i < markers_.size(); ++i) { if ((markers_[i].image == image1 || markers_[i].image == image2) && - std::binary_search(intersection.begin(),intersection.end(), + std::binary_search(intersection.begin(), intersection.end(), markers_[i].track)) { markers.push_back(markers_[i]); } diff --git a/extern/libmv/libmv/tracking/brute_region_tracker.cc b/extern/libmv/libmv/tracking/brute_region_tracker.cc index ef36dffb56d..01279a04347 100644 --- a/extern/libmv/libmv/tracking/brute_region_tracker.cc +++ b/extern/libmv/libmv/tracking/brute_region_tracker.cc @@ -63,13 +63,13 @@ void *aligned_malloc(int size, int alignment) { #elif __FreeBSD__ void *result; - if(posix_memalign(&result, alignment, size)) { + if (posix_memalign(&result, alignment, size)) { // non-zero means allocation error // either no allocation or bad alignment value return NULL; } return result; -#else // This is for Linux. +#else // This is for Linux. return memalign(alignment, size); #endif } @@ -107,7 +107,7 @@ bool RegionIsInBounds(const FloatImage &image1, #ifdef __SSE2__ -// Compute the sub of absolute differences between the arrays "a" and "b". +// Compute the sub of absolute differences between the arrays "a" and "b". // The array "a" is assumed to be 16-byte aligned, while "b" is not. The // result is returned as the first and third elements of __m128i if // interpreted as a 4-element 32-bit integer array. The SAD is the sum of the @@ -122,7 +122,7 @@ inline static __m128i SumOfAbsoluteDifferencesContiguousSSE( unsigned int size, __m128i sad) { // Do the bulk of the work as 16-way integer operations. - for(unsigned int j = 0; j < size / 16; j++) { + for (unsigned int j = 0; j < size / 16; j++) { sad = _mm_add_epi32(sad, _mm_sad_epu8( _mm_load_si128 ((__m128i*)(a + 16 * j)), _mm_loadu_si128((__m128i*)(b + 16 * j)))); } @@ -307,7 +307,8 @@ bool BruteRegionTracker::Track(const FloatImage &image1, // Convert the search area directly to bytes without sampling. unsigned char *search_area; int search_area_stride; - FloatArrayToByteArrayWithPadding(image_and_gradient2, &search_area, &search_area_stride); + FloatArrayToByteArrayWithPadding(image_and_gradient2, &search_area, + &search_area_stride); // Try all possible locations inside the search area. Yes, everywhere. int best_i = -1, best_j = -1, best_sad = INT_MAX; @@ -361,9 +362,11 @@ bool BruteRegionTracker::Track(const FloatImage &image1, // Compute the Pearson product-moment correlation coefficient to check // for sanity. - double correlation = PearsonProductMomentCorrelation(image_and_gradient1_sampled, - image_and_gradient2_sampled, - pattern_width); + double correlation = PearsonProductMomentCorrelation( + image_and_gradient1_sampled, + image_and_gradient2_sampled, + pattern_width); + LG << "Final correlation: " << correlation; if (correlation < minimum_correlation) { diff --git a/extern/libmv/libmv/tracking/brute_region_tracker.h b/extern/libmv/libmv/tracking/brute_region_tracker.h index 8ff0c1b7965..a699c42ee92 100644 --- a/extern/libmv/libmv/tracking/brute_region_tracker.h +++ b/extern/libmv/libmv/tracking/brute_region_tracker.h @@ -30,7 +30,7 @@ struct BruteRegionTracker : public RegionTracker { BruteRegionTracker() : half_window_size(4), minimum_correlation(0.78) {} - + virtual ~BruteRegionTracker() {} // Tracker interface. diff --git a/extern/libmv/libmv/tracking/esm_region_tracker.cc b/extern/libmv/libmv/tracking/esm_region_tracker.cc index a8dc46d439b..1e44012e208 100644 --- a/extern/libmv/libmv/tracking/esm_region_tracker.cc +++ b/extern/libmv/libmv/tracking/esm_region_tracker.cc @@ -72,7 +72,7 @@ bool EsmRegionTracker::Track(const FloatImage &image1, << ", hw=" << half_window_size << "."; return false; } - + // XXX // TODO(keir): Delete the block between the XXX's once the planar tracker is // integrated into blender. @@ -101,7 +101,7 @@ bool EsmRegionTracker::Track(const FloatImage &image1, options.max_iterations = 20; options.sigma = sigma; options.use_esm = true; - + TrackRegionResult result; TrackRegion(image1, image2, xx1, yy1, options, xx2, yy2, &result); @@ -129,7 +129,7 @@ bool EsmRegionTracker::Track(const FloatImage &image1, &image_and_gradient1_sampled); // Step 0: Initialize delta = 0.01. - // + // // Ignored for my "normal" LM loop. // Step 1: Warp I with W(x, p) to compute I(W(x; p). @@ -179,8 +179,7 @@ bool EsmRegionTracker::Track(const FloatImage &image1, } } - double tau = 1e-4, eps1, eps2, eps3; - eps1 = eps2 = eps3 = 1e-15; + double tau = 1e-4; double mu = tau * std::max(H_image1(0, 0), H_image1(1, 1)); double nu = M_E; @@ -201,7 +200,7 @@ bool EsmRegionTracker::Track(const FloatImage &image1, image_and_gradient1_sampled(r, c, 2)); Vec2 g2(image_and_gradient2_sampled[current_image](r, c, 1), image_and_gradient2_sampled[current_image](r, c, 2)); - Vec2 g = g1 + g2; // Should be / 2.0, but do that outside the loop. + Vec2 g = g1 + g2; // Should be / 2.0, but do that outside the loop. H += g * g.transpose(); } } @@ -282,9 +281,10 @@ bool EsmRegionTracker::Track(const FloatImage &image1, if (d.squaredNorm() < min_update_squared_distance) { // Compute the Pearson product-moment correlation coefficient to check // for sanity. - double correlation = PearsonProductMomentCorrelation(image_and_gradient1_sampled, - image_and_gradient2_sampled[new_image], - width); + double correlation = PearsonProductMomentCorrelation( + image_and_gradient1_sampled, + image_and_gradient2_sampled[new_image], + width); LG << "Final correlation: " << correlation; // Note: Do the comparison here to handle nan's correctly (since all diff --git a/extern/libmv/libmv/tracking/esm_region_tracker.h b/extern/libmv/libmv/tracking/esm_region_tracker.h index 602b32f1675..97b8e27dba2 100644 --- a/extern/libmv/libmv/tracking/esm_region_tracker.h +++ b/extern/libmv/libmv/tracking/esm_region_tracker.h @@ -40,7 +40,7 @@ struct EsmRegionTracker : public RegionTracker { min_update_squared_distance(1e-4), sigma(0.9), minimum_correlation(0.78) {} - + virtual ~EsmRegionTracker() {} // Tracker interface. diff --git a/extern/libmv/libmv/tracking/hybrid_region_tracker.h b/extern/libmv/libmv/tracking/hybrid_region_tracker.h index a18341f0ce4..967d2afd1e5 100644 --- a/extern/libmv/libmv/tracking/hybrid_region_tracker.h +++ b/extern/libmv/libmv/tracking/hybrid_region_tracker.h @@ -34,7 +34,7 @@ class HybridRegionTracker : public RegionTracker { RegionTracker *fine_tracker) : coarse_tracker_(coarse_tracker), fine_tracker_(fine_tracker) {} - + virtual ~HybridRegionTracker() {} // Tracker interface. diff --git a/extern/libmv/libmv/tracking/klt_region_tracker.cc b/extern/libmv/libmv/tracking/klt_region_tracker.cc index c8e605de572..dbbf9f0b996 100644 --- a/extern/libmv/libmv/tracking/klt_region_tracker.cc +++ b/extern/libmv/libmv/tracking/klt_region_tracker.cc @@ -18,8 +18,9 @@ // 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/tracking/klt_region_tracker.h" + +#include "libmv/logging/logging.h" #include "libmv/image/image.h" #include "libmv/image/convolve.h" #include "libmv/image/sample.h" @@ -144,7 +145,8 @@ bool KltRegionTracker::Track(const FloatImage &image1, LG << "Determinant " << determinant << " is too small; failing tracking."; return false; } - LG << "x=" << *x2 << ", y=" << *y2 << ", dx=" << dx << ", dy=" << dy << ", det=" << determinant; + LG << "x=" << *x2 << ", y=" << *y2 << ", dx=" << dx << ", dy=" << dy + << ", det=" << determinant; // If the update is small, then we probably found the target. if (dx * dx + dy * dy < min_update_squared_distance) { diff --git a/extern/libmv/libmv/tracking/klt_region_tracker.h b/extern/libmv/libmv/tracking/klt_region_tracker.h index 2b2d8a9a49d..43977757084 100644 --- a/extern/libmv/libmv/tracking/klt_region_tracker.h +++ b/extern/libmv/libmv/tracking/klt_region_tracker.h @@ -33,7 +33,7 @@ struct KltRegionTracker : public RegionTracker { min_determinant(1e-6), min_update_squared_distance(1e-6), sigma(0.9) {} - + virtual ~KltRegionTracker() {} // Tracker interface. diff --git a/extern/libmv/libmv/tracking/lmicklt_region_tracker.cc b/extern/libmv/libmv/tracking/lmicklt_region_tracker.cc index 581e984b569..9e7446c7d08 100644 --- a/extern/libmv/libmv/tracking/lmicklt_region_tracker.cc +++ b/extern/libmv/libmv/tracking/lmicklt_region_tracker.cc @@ -79,7 +79,7 @@ bool LmickltRegionTracker::Track(const FloatImage &image1, << ", hw=" << half_window_size << "."; return false; } - + int width = 2 * half_window_size + 1; // TODO(keir): Avoid recomputing gradients for e.g. the pyramid tracker. @@ -100,7 +100,7 @@ bool LmickltRegionTracker::Track(const FloatImage &image1, &image_and_gradient1_sampled); // Step 0: Initialize delta = 0.01. - // + // // Ignored for my "normal" LM loop. double reasonable_error = @@ -152,8 +152,7 @@ bool LmickltRegionTracker::Track(const FloatImage &image1, } } - double tau = 1e-3, eps1, eps2, eps3; - eps1 = eps2 = eps3 = 1e-15; + double tau = 1e-3; double mu = tau * std::max(H(0, 0), H(1, 1)); double nu = 2.0; diff --git a/extern/libmv/libmv/tracking/lmicklt_region_tracker.h b/extern/libmv/libmv/tracking/lmicklt_region_tracker.h index 744f2dfe277..95f4ba5f9b5 100644 --- a/extern/libmv/libmv/tracking/lmicklt_region_tracker.h +++ b/extern/libmv/libmv/tracking/lmicklt_region_tracker.h @@ -40,7 +40,7 @@ struct LmickltRegionTracker : public RegionTracker { min_determinant(1e-6), min_update_squared_distance(1e-6), sigma(0.9) {} - + virtual ~LmickltRegionTracker() {} // Tracker interface. diff --git a/extern/libmv/libmv/tracking/pyramid_region_tracker.cc b/extern/libmv/libmv/tracking/pyramid_region_tracker.cc index c177f9c5a83..4db501050f3 100644 --- a/extern/libmv/libmv/tracking/pyramid_region_tracker.cc +++ b/extern/libmv/libmv/tracking/pyramid_region_tracker.cc @@ -18,13 +18,14 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/tracking/pyramid_region_tracker.h" + #include <vector> #include "libmv/image/convolve.h" #include "libmv/image/image.h" #include "libmv/image/sample.h" #include "libmv/logging/logging.h" -#include "libmv/tracking/pyramid_region_tracker.h" namespace libmv { diff --git a/extern/libmv/libmv/tracking/retrack_region_tracker.cc b/extern/libmv/libmv/tracking/retrack_region_tracker.cc index b3230b1b173..4d230086d28 100644 --- a/extern/libmv/libmv/tracking/retrack_region_tracker.cc +++ b/extern/libmv/libmv/tracking/retrack_region_tracker.cc @@ -18,11 +18,11 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. +#include "libmv/tracking/retrack_region_tracker.h" + #include <cmath> #include <vector> -#include "libmv/tracking/retrack_region_tracker.h" - namespace libmv { bool RetrackRegionTracker::Track(const FloatImage &image1, diff --git a/extern/libmv/libmv/tracking/track_region.cc b/extern/libmv/libmv/tracking/track_region.cc index 036b7c94966..6e9fb95654d 100644 --- a/extern/libmv/libmv/tracking/track_region.cc +++ b/extern/libmv/libmv/tracking/track_region.cc @@ -60,6 +60,8 @@ struct JetOps { } static void ScaleDerivative(double scale_by, T *value) { // For double, there is no derivative to scale. + (void) scale_by; // Ignored. + (void) value; // Ignored. } }; @@ -85,7 +87,9 @@ struct Chain { const FunctionType dfdx[kNumArgs], const ArgumentType x[kNumArgs]) { // In the default case of scalars, there's nothing to do since there are no - // derivatives to propagate. + // derivatives to propagate. + (void) dfdx; // Ignored. + (void) x; // Ignored. return f; } }; @@ -276,8 +280,8 @@ class PixelDifferenceCostFunctor { int num_samples_y, const Warp &warp) : options_(options), - image_and_gradient1_(image_and_gradient1), - image_and_gradient2_(image_and_gradient2), + image_and_gradient1_(image_and_gradient1), + image_and_gradient2_(image_and_gradient2), canonical_to_image1_(canonical_to_image1), num_samples_x_(num_samples_x), num_samples_y_(num_samples_y), @@ -348,7 +352,7 @@ class PixelDifferenceCostFunctor { // // Note that partial masks are not short circuited. To see why short // circuiting produces bitwise-exact same results, consider that the - // residual for each pixel is + // residual for each pixel is // // residual = mask * (src - dst) , // @@ -431,11 +435,10 @@ class PixelDifferenceCostFunctor { return true; } - // For normalized matching, the average and + // For normalized matching, the average and template<typename T> void ComputeNormalizingCoefficient(const T *warp_parameters, T *dst_mean) const { - *dst_mean = T(0.0); double num_samples = 0.0; for (int r = 0; r < num_samples_y_; ++r) { @@ -443,7 +446,7 @@ class PixelDifferenceCostFunctor { // Use the pre-computed image1 position. Vec2 image1_position(pattern_positions_(r, c, 0), pattern_positions_(r, c, 1)); - + // Sample the mask early; if it's zero, this pixel has no effect. This // allows early bailout from the expensive sampling that happens below. double mask_value = 1.0; @@ -484,28 +487,28 @@ class PixelDifferenceCostFunctor { LG << "Normalization for dst:" << *dst_mean; } - // TODO(keir): Consider also computing the cost here. - double PearsonProductMomentCorrelationCoefficient( - const double *warp_parameters) const { - for (int i = 0; i < Warp::NUM_PARAMETERS; ++i) { - VLOG(2) << "Correlation warp_parameters[" << i << "]: " - << warp_parameters[i]; - } + // TODO(keir): Consider also computing the cost here. + double PearsonProductMomentCorrelationCoefficient( + const double *warp_parameters) const { + for (int i = 0; i < Warp::NUM_PARAMETERS; ++i) { + VLOG(2) << "Correlation warp_parameters[" << i << "]: " + << warp_parameters[i]; + } - // The single-pass PMCC computation is somewhat numerically unstable, but - // it's sufficient for the tracker. - double sX = 0, sY = 0, sXX = 0, sYY = 0, sXY = 0; + // The single-pass PMCC computation is somewhat numerically unstable, but + // it's sufficient for the tracker. + double sX = 0, sY = 0, sXX = 0, sYY = 0, sXY = 0; - // Due to masking, it's important to account for fractional samples. - // For example, samples with a 50% mask are counted as a half sample. - double num_samples = 0; + // Due to masking, it's important to account for fractional samples. + // For example, samples with a 50% mask are counted as a half sample. + double num_samples = 0; - for (int r = 0; r < num_samples_y_; ++r) { - for (int c = 0; c < num_samples_x_; ++c) { + for (int r = 0; r < num_samples_y_; ++r) { + for (int c = 0; c < num_samples_x_; ++c) { // Use the pre-computed image1 position. Vec2 image1_position(pattern_positions_(r, c, 0), pattern_positions_(r, c, 1)); - + double mask_value = 1.0; if (options_.image1_mask != NULL) { mask_value = pattern_mask_(r, c); @@ -795,7 +798,7 @@ struct TranslationRotationWarp { // Obtain the rotation via orthorgonal procrustes. Mat2 correlation_matrix; for (int i = 0; i < 4; ++i) { - correlation_matrix += q1.CornerRelativeToCentroid(i) * + correlation_matrix += q1.CornerRelativeToCentroid(i) * q2.CornerRelativeToCentroid(i).transpose(); } Mat2 R = OrthogonalProcrustes(correlation_matrix); @@ -863,7 +866,7 @@ struct TranslationRotationScaleWarp { // Obtain the rotation via orthorgonal procrustes. Mat2 correlation_matrix; for (int i = 0; i < 4; ++i) { - correlation_matrix += q1.CornerRelativeToCentroid(i) * + correlation_matrix += q1.CornerRelativeToCentroid(i) * q2.CornerRelativeToCentroid(i).transpose(); } Mat2 R = OrthogonalProcrustes(correlation_matrix); @@ -938,7 +941,7 @@ struct AffineWarp { Vec2 v1 = q1.CornerRelativeToCentroid(i); Vec2 v2 = q2.CornerRelativeToCentroid(i); - Q1.row(2 * i + 0) << v1[0], v1[1], 0, 0 ; + Q1.row(2 * i + 0) << v1[0], v1[1], 0, 0; Q1.row(2 * i + 1) << 0, 0, v1[0], v1[1]; Q2(2 * i + 0) = v2[0]; @@ -1039,6 +1042,9 @@ struct HomographyWarp { void PickSampling(const double *x1, const double *y1, const double *x2, const double *y2, int *num_samples_x, int *num_samples_y) { + (void) x2; // Ignored. + (void) y2; // Ignored. + Vec2 a0(x1[0], y1[0]); Vec2 a1(x1[1], y1[1]); Vec2 a2(x1[2], y1[2]); @@ -1074,6 +1080,10 @@ void PickSampling(const double *x1, const double *y1, bool SearchAreaTooBigForDescent(const FloatImage &image2, const double *x2, const double *y2) { // TODO(keir): Check the bounds and enable only when it makes sense. + (void) image2; // Ignored. + (void) x2; // Ignored. + (void) y2; // Ignored. + return true; } @@ -1150,12 +1160,12 @@ void CreateBrutePattern(const double *x1, const double *y1, inverse_warp.Forward(inverse_warp.parameters, dst_x, dst_y, &src_x, &src_y); - + if (PointInQuad(x1, y1, src_x, src_y)) { (*pattern)(i, j) = SampleLinear(image1, src_y, src_x); (*mask)(i, j) = 1.0; if (image1_mask) { - (*mask)(i, j) = SampleLinear(*image1_mask, src_y, src_x);; + (*mask)(i, j) = SampleLinear(*image1_mask, src_y, src_x); } } else { (*pattern)(i, j) = 0.0; @@ -1218,7 +1228,7 @@ bool BruteTranslationOnlyInitialize(const FloatImage &image1, // // TODO(keir): There are a number of possible optimizations here. One choice // is to make a grid and only try one out of every N possible samples. - // + // // Another, slightly more clever idea, is to compute some sort of spatial // frequency distribution of the pattern patch. If the spatial resolution is // high (e.g. a grating pattern or fine lines) then checking every possible @@ -1375,7 +1385,7 @@ void TemplatedTrackRegion(const FloatImage &image1, num_samples_x, num_samples_y, warp); - problem.AddResidualBlock( + problem.AddResidualBlock( new ceres::AutoDiffCostFunction< PixelDifferenceCostFunctor<Warp>, ceres::DYNAMIC, diff --git a/extern/libmv/libmv/tracking/trklt_region_tracker.cc b/extern/libmv/libmv/tracking/trklt_region_tracker.cc index f19315b6b11..05ef3d1d272 100644 --- a/extern/libmv/libmv/tracking/trklt_region_tracker.cc +++ b/extern/libmv/libmv/tracking/trklt_region_tracker.cc @@ -158,7 +158,8 @@ bool TrkltRegionTracker::Track(const FloatImage &image1, LG << "Determinant " << determinant << " is too small; failing tracking."; return false; } - LG << "x=" << *x2 << ", y=" << *y2 << ", dx=" << d[0] << ", dy=" << d[1] << ", det=" << determinant; + LG << "x=" << *x2 << ", y=" << *y2 << ", dx=" << d[0] << ", dy=" << d[1] + << ", det=" << determinant; // If the update is small, then we probably found the target. diff --git a/extern/libmv/third_party/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/CMakeLists.txt index b71fe1d5cdb..e515280826b 100644 --- a/extern/libmv/third_party/ceres/CMakeLists.txt +++ b/extern/libmv/third_party/ceres/CMakeLists.txt @@ -141,6 +141,7 @@ set(SRC include/ceres/solver.h include/ceres/types.h internal/ceres/array_utils.h + internal/ceres/blas.h internal/ceres/block_evaluate_preparer.h internal/ceres/block_jacobian_writer.h internal/ceres/block_jacobi_preconditioner.h diff --git a/extern/libmv/third_party/ceres/ChangeLog b/extern/libmv/third_party/ceres/ChangeLog index 458a045d8be..46c7b6ac291 100644 --- a/extern/libmv/third_party/ceres/ChangeLog +++ b/extern/libmv/third_party/ceres/ChangeLog @@ -1,3 +1,185 @@ +commit 520d35ef22dbcb05e344451c03ae64304e524a06 +Author: Sameer Agarwal <sameeragarwal@google.com> +Date: Thu Apr 4 08:16:02 2013 -0700 + + Further BLAS improvements. + + 1. Switch to Eigen's implementation when all dimensions are fixed. + 2. Use lazyProduct for eigen matrix-vector product. This brings + eigen's performance on iterative_schur closer to what it used + to be before the last commit. There is however still an + improvement to be had by using the naive implementation when + the matrix and vector have dynamic dimensions. + + BENCHMARK + HEAD CHANGE + + problem-16-22106-pre.txt + gcc-eigen sparse_schur 0.859 gcc-eigen sparse_schur 0.853 + clang-eigen sparse_schur 0.848 clang-eigen sparse_schur 0.850 + gcc-blas sparse_schur 0.956 gcc-blas sparse_schur 0.865 + clang-blas sparse_schur 0.954 clang-blas sparse_schur 0.858 + gcc-eigen iterative_schur 4.656 gcc-eigen iterative_schur 3.271 + clang-eigen iterative_schur 4.664 clang-eigen iterative_schur 3.307 + gcc-blas iterative_schur 2.598 gcc-blas iterative_schur 2.620 + clang-blas iterative_schur 2.554 clang-blas iterative_schur 2.567 + + problem-49-7776-pre.txt + gcc-eigen sparse_schur 0.477 gcc-eigen sparse_schur 0.472 + clang-eigen sparse_schur 0.475 clang-eigen sparse_schur 0.479 + gcc-blas sparse_schur 0.521 gcc-blas sparse_schur 0.469 + clang-blas sparse_schur 0.508 clang-blas sparse_schur 0.471 + gcc-eigen iterative_schur 3.172 gcc-eigen iterative_schur 2.088 + clang-eigen iterative_schur 3.161 clang-eigen iterative_schur 2.079 + gcc-blas iterative_schur 1.701 gcc-blas iterative_schur 1.720 + clang-blas iterative_schur 1.708 clang-blas iterative_schur 1.694 + + problem-245-198739-pre.txt + gcc-eigen sparse_schur 28.092 gcc-eigen sparse_schur 28.233 + clang-eigen sparse_schur 28.148 clang-eigen sparse_schur 28.400 + gcc-blas sparse_schur 30.919 gcc-blas sparse_schur 28.110 + clang-blas sparse_schur 31.001 clang-blas sparse_schur 28.407 + gcc-eigen iterative_schur 63.095 gcc-eigen iterative_schur 43.694 + clang-eigen iterative_schur 63.412 clang-eigen iterative_schur 43.473 + gcc-blas iterative_schur 33.353 gcc-blas iterative_schur 33.321 + clang-blas iterative_schur 33.276 clang-blas iterative_schur 33.278 + + problem-257-65132-pre.txt + gcc-eigen sparse_schur 3.687 gcc-eigen sparse_schur 3.629 + clang-eigen sparse_schur 3.669 clang-eigen sparse_schur 3.652 + gcc-blas sparse_schur 3.947 gcc-blas sparse_schur 3.673 + clang-blas sparse_schur 3.952 clang-blas sparse_schur 3.678 + gcc-eigen iterative_schur 121.512 gcc-eigen iterative_schur 76.833 + clang-eigen iterative_schur 123.547 clang-eigen iterative_schur 78.763 + gcc-blas iterative_schur 68.334 gcc-blas iterative_schur 68.612 + clang-blas iterative_schur 67.793 clang-blas iterative_schur 68.266 + + Notes: + + 1. Naive BLAS was a bit worse than eigen on fixed sized matrices. We did not see this + before because of the different inlining thresholds. Fixing this boosted eigen's + performance. Also the disparity between gcc and clang has gone away. + + 2. SPARSE_SCHUR performance remains the same, since it is only testing static sized + matrices. + + 3. ITERATIVE_SCHUR performance goes up substantially due to the lazyProduct change, + but even there, since most of the products are dynamic sized, the naive implementation + wins handily. + + Change-Id: Idc17f35b9c68aaebb1b2e131adf3af8374a85a4c + +commit 25ac54807eedf16fd6c34efc390901ee549a7d14 +Author: Sameer Agarwal <sameeragarwal@google.com> +Date: Wed Apr 3 18:51:27 2013 -0700 + + Speed up Jets. + + Change-Id: I101bac1b1a1cf72ca49ffcf843b73c0ef5a6dfcb + +commit 3d6eceb45cf27024865908f0c10a5c2b0f8719cf +Author: Sameer Agarwal <sameeragarwal@google.com> +Date: Tue Apr 2 21:45:48 2013 -0700 + + Replace more instances of Eigen GEMV with Ceres BLAS. + + With this ITERATIVE_SCHUR with JACOBI preconditioner went down from + 280 seconds to 150 seconds on problem-744-543562-pre.txt. + + Change-Id: I4f319c1108421e8d59f58654a4c0576ad65df609 + +commit 296fa9b1279ee1900c8ae32d70e97cd10fc0b46b +Author: Sameer Agarwal <sameeragarwal@google.com> +Date: Tue Apr 2 09:44:15 2013 -0700 + + Replace Eigen block operations with small GEMM and GEMV loops. + + 1. Add Matrix-Matrix and Matrix-Vector multiply functions. + 2. Replace Eigen usage in SchurEliminator with these custom + matrix operations. + 3. Save on some memory allocations in ChunkOuterProduct. + 4. Replace LDLT with LLT. + + As a result on problem-16-22106-pre.txt, the linear solver time + goes down from 1.2s to 0.64s. + + Change-Id: I2daa667960e0a1e8834489965a30be31f37fd87f + +commit 222ca20e8facf706582fe696b7f41247391eac12 +Author: Sameer Agarwal <sameeragarwal@google.com> +Date: Mon Apr 1 09:11:07 2013 -0700 + + SuiteSparse cleanup. + + 1. Silence CHOLMOD's indefiniteness warnings. + 2. Add a comment about how the error handling in suitesparse.cc + needs to be improved. + 3. Move the analysis logging into suitesparse.cc and out of the + three callsites. + + Change-Id: Idd396b8ea4bf59fc1ffc7f9fcbbc7b38ed71643c + +commit b7ba93459b7f584eedb1a9f42f3d06bccabd33dc +Author: Petter Strandmark <petter.strandmark@gmail.com> +Date: Tue Feb 19 12:52:58 2013 +0100 + + Enable larger tuple sizes for Visual Studio 2012. + + Visual Studio 2012 does not have variadic templates and implements + tuples differently. By default, only sizes up to 5 are supported, + which conflicts with Gtest. + + Change-Id: Ieb8d59e4329863cbfa2729d8a76db0714c08d259 + +commit 564a83fcc690ac8383bf52a782c45757ae7fa2ad +Author: Sameer Agarwal <sameeragarwal@google.com> +Date: Tue Mar 26 11:11:43 2013 -0700 + + Lint cleanup from William Rucklidge. + + Change-Id: I8d4a0aa3e264775d20e99a6b5265f3023de92560 + +commit cbe64827becbbaab5b435a71bf00353b4ddd026b +Author: Sameer Agarwal <sameeragarwal@google.com> +Date: Mon Mar 25 17:39:53 2013 -0700 + + Update documentation + + Change-Id: Iea3c4b5409e593b1fb070a491ba8a479db32ca58 + +commit 802639c89603c9541e624766349d1989a1f641c0 +Author: Pablo Speciale <pablo.speciale@gmail.com> +Date: Mon Mar 25 20:53:45 2013 -0700 + + ceresproblem label was incorrect + + Change-Id: I3e210375adba4fa50ff3c25398b20a65d241cb35 + +commit 6bcb8d9c304a3b218f8788018dfdfe368bb7d60c +Author: Pablo Speciale <pablo.speciale@gmail.com> +Date: Mon Mar 25 16:40:26 2013 -0700 + + Compiling against static or shared library + + Change-Id: I3fb35e9a49f90b8894f59dde49c90a7c2dd74b0a + +commit 619cfe692020c078275b68eac2167232fafdfffb +Author: Sameer Agarwal <sameeragarwal@google.com> +Date: Mon Mar 25 14:03:41 2013 -0700 + + Update version history + + Change-Id: I1d036efad1507efd19d8581f147b38170b1f0543 + +commit 6ae34757850a5fa8213e0d1a540d9d75d6840a08 +Author: Pablo Speciale <pablo.speciale@gmail.com> +Date: Sun Mar 24 22:30:52 2013 -0700 + + Added documentation regarding the use of Ceres with cmake (once installed) + Commets about the flag ``BUILD_DOCUMENTATION=ON`` + + Change-Id: I8814927e60af190c8043bfc36e77fe76bfe6f562 + commit f46de9e697eb5b8756084615e29ded48600a4d39 Author: Sergey Sharybin <sergey.vfx@gmail.com> Date: Thu Mar 21 15:31:35 2013 +0600 @@ -437,171 +619,3 @@ Date: Sun Feb 24 14:15:45 2013 -0800 Minor release script fixes. Change-Id: Ifd0a7f4f584c85d4d9574eca46094b372a8d7aff - -commit b53c9667f508c125b8aa833e7a063fa44ef8a98e -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Mon Feb 25 01:14:26 2013 +0600 - - Solve No Previous Prototype GCC warning - - In some cases there were missing includes of own - header files from implementation files. - - In other cases moved function which are only used - within single file into an anonymous namespace. - - Change-Id: I2c6b411bcfbc521e2a5f21265dc8e009a548b1c8 - -commit 267ccc45a3e875bf87832a8ad615be690b4926d3 -Author: Sergey Sharybin <sergey.vfx@gmail.com> -Date: Mon Feb 25 01:04:16 2013 +0600 - - Fix for MinGW build on Windows - - GG_LONGLONG and GG_ULONGLONG shall use LL and ULL suffixes, - since MinGW is actuall a GCC compiler. - - Solved by checking whether compilation happens with MinGW - or not using standard MinGW's __MINGW32__ and __MINGW64__ - definitions. - - Change-Id: I789b34f6342a56ba42f4b280f7242700022ab7a1 - -commit 509f68cfe3fd13b794c4e67ff38c761407c858cf -Author: Sameer Agarwal <sameeragarwal@google.com> -Date: Wed Feb 20 01:39:03 2013 -0800 - - Problem::Evaluate implementation. - - 1. Add Problem::Evaluate and tests. - 2. Remove Solver::Summary::initial/final_* - 3. Remove Solver::Options::return_* members. - 4. Various cpplint cleanups. - - Change-Id: I4266de53489896f72d9c6798c5efde6748d68a47 - -commit d4a0bf86d688d1b68e00ff302858de5a4e0d9727 -Author: Keir Mierle <mierle@gmail.com> -Date: Sun Feb 24 10:35:44 2013 -0800 - - Fix threading build on Windows. - - On Windows, including the "windows.h" header defines an enormous number of - symbols; some of which are macros with common names. In particular, "ERROR" and - "min" and "max" get defined. This causes clashes when user code references - these names in a context other than the intended use in windows.h. - - To deal with this, the Microsoft engineers added the ability to control the - definition of these symbols by adding extra defines. In particular, including - windows.h in the following way - - #define NOGDI - #define NOMINMAX - - will reduce the number of macros defined. This way they will not conflict with - other uses in Ceres. For example, numeric_limits<double>::max() is impossible - to call without defining NOMINMAX. - - Change-Id: I166f5d3bb6dc0e2e4b2ebf800fb19e49206f7874 - -commit beb4505311011130a7e54632137b0fbb5824cc9b -Author: Sameer Agarwal <sameeragarwal@google.com> -Date: Fri Feb 22 13:37:01 2013 -0800 - - Minor fixes - - Based on William Rucklidge's review, including - a nasty bug in parameter block removal. - - Change-Id: I3a692e589f600ff560ecae9fa85bb0b76063d403 - -commit 9a88bd7c4b40e2a1e0cd9b0dc09a3517c467e04e -Author: Sameer Agarwal <sameeragarwal@google.com> -Date: Tue Feb 19 13:09:12 2013 -0800 - - Minor bug fixes - - Change-Id: I94e4521adf76a6c77db954c4a8955168e9d37b55 - -commit 956ed7e8f2054623615e6ae3601055d613897f26 -Author: Sameer Agarwal <sameeragarwal@google.com> -Date: Tue Feb 19 07:06:15 2013 -0800 - - Various minor fixes. - - 1. Unused variable warnings and fixes. - 2. Minor documentation update. - - Change-Id: I815588a5806df1030a7c8750f4fb594c503f8998 - -commit 3e2c4ef9ad35e94198f4f3367b99fd91e26996a1 -Author: Keir Mierle <mierle@gmail.com> -Date: Sun Feb 17 12:37:55 2013 -0800 - - Add adapters for column/row-major matrices to rotation.h - - This patch introduces a matrix wrapper (MatrixAdapter) that allows to - transparently pass pointers to row-major or column-major matrices - to the conversion functions. - - Change-Id: I7f1683a8722088cffcc542f593ce7eb46fca109b - -commit 04938efe4bedec112083c5ceb227ba004f96bd01 -Author: Keir Mierle <mierle@gmail.com> -Date: Sun Feb 17 12:37:55 2013 -0800 - - Add support for removing parameter and residual blocks. - - This adds support for removing parameter and residual blocks. - There are two modes of operation: in the first, removals of - paremeter blocks are expensive, since each remove requires - scanning all residual blocks to find ones that depend on the - removed parameter. In the other, extra memory is sacrificed to - maintain a list of the residuals a parameter block depends on, - removing the need to scan. In both cases, removing residual blocks - is fast. - - As a caveat, any removals destroys the ordering of the parameters, - so the residuals or jacobian returned from Solver::Solve() is - meaningless. There is some debate on the best way to handle this; - the details remain for a future change. - - This also adds some overhead, even in the case that fast removals - are not requested: - - - 1 int32 to each residual, to track its position in the program. - - 1 pointer to each parameter, to store the dependent residuals. - - Change-Id: I71dcac8656679329a15ee7fc12c0df07030c12af - -commit fa21df8cd969bb257b87c9ef7c0147d8d5ea8725 -Author: Sameer Agarwal <sameeragarwal@google.com> -Date: Mon Feb 18 08:48:52 2013 -0800 - - Add script for building documentation. - - Update make_release - - Minor documentation fixes. - - Change-Id: I1248ec3f58be66b5929aee6f2aa392c15d53ed83 - -commit 290b975d1d4eba44205bbeb0fa6b3ce8a6fa4a0c -Author: Sameer Agarwal <sameeragarwal@google.com> -Date: Sun Feb 17 16:50:37 2013 -0800 - - Preconditioner refactoring. - - 1. Added a Preconditioner interface. - 2. SCHUR_JACOBI is now its own class and is independent of - SuiteSparse. - - Change-Id: Id912ab19cf3736e61d1b90ddaf5bfba33e877ec4 - -commit d010de543530001fa917501a13ba02879c8ea52f -Author: Sameer Agarwal <sameeragarwal@google.com> -Date: Fri Feb 15 14:26:56 2013 -0800 - - Solver::Summary::FullReport() supports line search now. - - Change-Id: Ib08d300198b85d9732cfb5785af4235ca4bd5226 diff --git a/extern/libmv/third_party/ceres/files.txt b/extern/libmv/third_party/ceres/files.txt index 8f4b7b97b50..0c60e5a055a 100644 --- a/extern/libmv/third_party/ceres/files.txt +++ b/extern/libmv/third_party/ceres/files.txt @@ -31,6 +31,7 @@ include/ceres/solver.h include/ceres/types.h internal/ceres/array_utils.cc internal/ceres/array_utils.h +internal/ceres/blas.h internal/ceres/block_evaluate_preparer.cc internal/ceres/block_evaluate_preparer.h internal/ceres/block_jacobian_writer.cc diff --git a/extern/libmv/third_party/ceres/include/ceres/jet.h b/extern/libmv/third_party/ceres/include/ceres/jet.h index 96e2256fd02..1238123a8fb 100644 --- a/extern/libmv/third_party/ceres/include/ceres/jet.h +++ b/extern/libmv/third_party/ceres/include/ceres/jet.h @@ -349,7 +349,11 @@ Jet<T, N> operator/(const Jet<T, N>& f, // // which holds because v*v = 0. h.a = f.a / g.a; - h.v = (f.v - f.a / g.a * g.v) / g.a; + const T g_a_inverse = 1.0 / g.a; + const T f_a_by_g_a = f.a * g_a_inverse; + for (int i = 0; i < N; ++i) { + h.v[i] = (f.v[i] - f_a_by_g_a * g.v[i]) * g_a_inverse; + } return h; } @@ -358,7 +362,8 @@ template<typename T, int N> inline Jet<T, N> operator/(T s, const Jet<T, N>& g) { Jet<T, N> h; h.a = s / g.a; - h.v = - s * g.v / (g.a * g.a); + const T minus_s_g_a_inverse2 = -s / (g.a * g.a); + h.v = g.v * minus_s_g_a_inverse2; return h; } @@ -366,8 +371,9 @@ Jet<T, N> operator/(T s, const Jet<T, N>& g) { template<typename T, int N> inline Jet<T, N> operator/(const Jet<T, N>& f, T s) { Jet<T, N> h; - h.a = f.a / s; - h.v = f.v / s; + const T s_inverse = 1.0 / s; + h.a = f.a * s_inverse; + h.v = f.v * s_inverse; return h; } @@ -425,7 +431,8 @@ template <typename T, int N> inline Jet<T, N> log(const Jet<T, N>& f) { Jet<T, N> g; g.a = log(f.a); - g.v = f.v / f.a; + const T a_inverse = T(1.0) / f.a; + g.v = f.v * a_inverse; return g; } @@ -443,7 +450,8 @@ template <typename T, int N> inline Jet<T, N> sqrt(const Jet<T, N>& f) { Jet<T, N> g; g.a = sqrt(f.a); - g.v = f.v / (T(2.0) * g.a); + const T two_a_inverse = 1.0 / (T(2.0) * g.a); + g.v = f.v * two_a_inverse; return g; } @@ -452,7 +460,7 @@ template <typename T, int N> inline Jet<T, N> cos(const Jet<T, N>& f) { Jet<T, N> g; g.a = cos(f.a); - T sin_a = sin(f.a); + const T sin_a = sin(f.a); g.v = - sin_a * f.v; return g; } @@ -462,7 +470,8 @@ template <typename T, int N> inline Jet<T, N> acos(const Jet<T, N>& f) { Jet<T, N> g; g.a = acos(f.a); - g.v = - T(1.0) / sqrt(T(1.0) - f.a * f.a) * f.v; + const T tmp = - T(1.0) / sqrt(T(1.0) - f.a * f.a); + g.v = tmp * f.v; return g; } @@ -471,7 +480,7 @@ template <typename T, int N> inline Jet<T, N> sin(const Jet<T, N>& f) { Jet<T, N> g; g.a = sin(f.a); - T cos_a = cos(f.a); + const T cos_a = cos(f.a); g.v = cos_a * f.v; return g; } @@ -481,7 +490,8 @@ template <typename T, int N> inline Jet<T, N> asin(const Jet<T, N>& f) { Jet<T, N> g; g.a = asin(f.a); - g.v = T(1.0) / sqrt(T(1.0) - f.a * f.a) * f.v; + const T tmp = T(1.0) / sqrt(T(1.0) - f.a * f.a); + g.v = tmp * f.v; return g; } diff --git a/extern/libmv/third_party/ceres/internal/ceres/blas.h b/extern/libmv/third_party/ceres/internal/ceres/blas.h new file mode 100644 index 00000000000..12667d09e55 --- /dev/null +++ b/extern/libmv/third_party/ceres/internal/ceres/blas.h @@ -0,0 +1,496 @@ +// Ceres Solver - A fast non-linear least squares minimizer +// Copyright 2013 Google Inc. All rights reserved. +// http://code.google.com/p/ceres-solver/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, +// this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors may be +// used to endorse or promote products derived from this software without +// specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +// +// Author: sameeragarwal@google.com (Sameer Agarwal) +// +// Simple blas functions for use in the Schur Eliminator. These are +// fairly basic implementations which already yield a significant +// speedup in the eliminator performance. + +#ifndef CERES_INTERNAL_BLAS_H_ +#define CERES_INTERNAL_BLAS_H_ + +#include "ceres/internal/eigen.h" +#include "glog/logging.h" + +namespace ceres { +namespace internal { + +// Remove the ".noalias()" annotation from the matrix matrix +// mutliplies to produce a correct build with the Android NDK, +// including versions 6, 7, 8, and 8b, when built with STLPort and the +// non-standalone toolchain (i.e. ndk-build). This appears to be a +// compiler bug; if the workaround is not in place, the line +// +// block.noalias() -= A * B; +// +// gets compiled to +// +// block.noalias() += A * B; +// +// which breaks schur elimination. Introducing a temporary by removing the +// .noalias() annotation causes the issue to disappear. Tracking this +// issue down was tricky, since the test suite doesn't run when built with +// the non-standalone toolchain. +// +// TODO(keir): Make a reproduction case for this and send it upstream. +#ifdef CERES_WORK_AROUND_ANDROID_NDK_COMPILER_BUG +#define CERES_MAYBE_NOALIAS +#else +#define CERES_MAYBE_NOALIAS .noalias() +#endif + +// For the matrix-matrix functions below, there are three functions +// for each functionality. Foo, FooNaive and FooEigen. Foo is the one +// to be called by the user. FooNaive is a basic loop based +// implementation and FooEigen uses Eigen's implementation. Foo +// chooses between FooNaive and FooEigen depending on how many of the +// template arguments are fixed at compile time. Currently, FooEigen +// is called if all matrix dimenions are compile time +// constants. FooNaive is called otherwise. This leads to the best +// performance currently. +// +// TODO(sameeragarwal): Benchmark and simplify the matrix-vector +// functions. + +// C op A * B; +// +// where op can be +=, -=, or =. +// +// The template parameters (kRowA, kColA, kRowB, kColB) allow +// specialization of the loop at compile time. If this information is +// not available, then Eigen::Dynamic should be used as the template +// argument. +// +// kOperation = 1 -> C += A * B +// kOperation = -1 -> C -= A * B +// kOperation = 0 -> C = A * B +// +// The function can write into matrices C which are larger than the +// matrix A * B. This is done by specifying the true size of C via +// row_stride_c and col_stride_c, and then indicating where A * B +// should be written into by start_row_c and start_col_c. +// +// Graphically if row_stride_c = 10, col_stride_c = 12, start_row_c = +// 4 and start_col_c = 5, then if A = 3x2 and B = 2x4, we get +// +// ------------ +// ------------ +// ------------ +// ------------ +// -----xxxx--- +// -----xxxx--- +// -----xxxx--- +// ------------ +// ------------ +// ------------ +// +template<int kRowA, int kColA, int kRowB, int kColB, int kOperation> +inline void MatrixMatrixMultiplyEigen(const double* A, + const int num_row_a, + const int num_col_a, + const double* B, + const int num_row_b, + const int num_col_b, + double* C, + const int start_row_c, + const int start_col_c, + const int row_stride_c, + const int col_stride_c) { + const typename EigenTypes<kRowA, kColA>::ConstMatrixRef Aref(A, num_row_a, num_col_a); + const typename EigenTypes<kRowB, kColB>::ConstMatrixRef Bref(B, num_row_b, num_col_b); + MatrixRef Cref(C, row_stride_c, col_stride_c); + Eigen::Block<MatrixRef, kRowA, kColB> block(Cref, + start_row_c, start_col_c, + num_row_a, num_col_b); + if (kOperation > 0) { + block CERES_MAYBE_NOALIAS += Aref * Bref; + } else if (kOperation < 0) { + block CERES_MAYBE_NOALIAS -= Aref * Bref; + } else { + block CERES_MAYBE_NOALIAS = Aref * Bref; + } +} + +template<int kRowA, int kColA, int kRowB, int kColB, int kOperation> +inline void MatrixMatrixMultiplyNaive(const double* A, + const int num_row_a, + const int num_col_a, + const double* B, + const int num_row_b, + const int num_col_b, + double* C, + const int start_row_c, + const int start_col_c, + const int row_stride_c, + const int col_stride_c) { + DCHECK_GT(num_row_a, 0); + DCHECK_GT(num_col_a, 0); + DCHECK_GT(num_row_b, 0); + DCHECK_GT(num_col_b, 0); + DCHECK_GE(start_row_c, 0); + DCHECK_GE(start_col_c, 0); + DCHECK_GT(row_stride_c, 0); + DCHECK_GT(col_stride_c, 0); + + DCHECK((kRowA == Eigen::Dynamic) || (kRowA == num_row_a)); + DCHECK((kColA == Eigen::Dynamic) || (kColA == num_col_a)); + DCHECK((kRowB == Eigen::Dynamic) || (kRowB == num_row_b)); + DCHECK((kColB == Eigen::Dynamic) || (kColB == num_col_b)); + + const int NUM_ROW_A = (kRowA != Eigen::Dynamic ? kRowA : num_row_a); + const int NUM_COL_A = (kColA != Eigen::Dynamic ? kColA : num_col_a); + const int NUM_ROW_B = (kColB != Eigen::Dynamic ? kRowB : num_row_b); + const int NUM_COL_B = (kColB != Eigen::Dynamic ? kColB : num_col_b); + DCHECK_EQ(NUM_COL_A, NUM_ROW_B); + + const int NUM_ROW_C = NUM_ROW_A; + const int NUM_COL_C = NUM_COL_B; + DCHECK_LT(start_row_c + NUM_ROW_C, row_stride_c); + DCHECK_LT(start_col_c + NUM_COL_C, col_stride_c); + + for (int row = 0; row < NUM_ROW_C; ++row) { + for (int col = 0; col < NUM_COL_C; ++col) { + double tmp = 0.0; + for (int k = 0; k < NUM_COL_A; ++k) { + tmp += A[row * NUM_COL_A + k] * B[k * NUM_COL_B + col]; + } + + const int index = (row + start_row_c) * col_stride_c + start_col_c + col; + if (kOperation > 0) { + C[index] += tmp; + } else if (kOperation < 0) { + C[index] -= tmp; + } else { + C[index] = tmp; + } + } + } +} + +template<int kRowA, int kColA, int kRowB, int kColB, int kOperation> +inline void MatrixMatrixMultiply(const double* A, + const int num_row_a, + const int num_col_a, + const double* B, + const int num_row_b, + const int num_col_b, + double* C, + const int start_row_c, + const int start_col_c, + const int row_stride_c, + const int col_stride_c) { +#ifdef CERES_NO_CUSTOM_BLAS + MatrixMatrixMultiplyEigen<kRowA, kColA, kRowB, kColB, kOperation>( + A, num_row_a, num_col_a, + B, num_row_b, num_col_b, + C, start_row_c, start_col_c, row_stride_c, col_stride_c); + return; + +#else + + if (kRowA != Eigen::Dynamic && kColA != Eigen::Dynamic && + kRowB != Eigen::Dynamic && kColB != Eigen::Dynamic) { + MatrixMatrixMultiplyEigen<kRowA, kColA, kRowB, kColB, kOperation>( + A, num_row_a, num_col_a, + B, num_row_b, num_col_b, + C, start_row_c, start_col_c, row_stride_c, col_stride_c); + } else { + MatrixMatrixMultiplyNaive<kRowA, kColA, kRowB, kColB, kOperation>( + A, num_row_a, num_col_a, + B, num_row_b, num_col_b, + C, start_row_c, start_col_c, row_stride_c, col_stride_c); + } + +#endif +} + + +// C op A' * B; +// +// where op can be +=, -=, or =. +// +// The template parameters (kRowA, kColA, kRowB, kColB) allow +// specialization of the loop at compile time. If this information is +// not available, then Eigen::Dynamic should be used as the template +// argument. +// +// kOperation = 1 -> C += A' * B +// kOperation = -1 -> C -= A' * B +// kOperation = 0 -> C = A' * B +// +// The function can write into matrices C which are larger than the +// matrix A' * B. This is done by specifying the true size of C via +// row_stride_c and col_stride_c, and then indicating where A * B +// should be written into by start_row_c and start_col_c. +// +// Graphically if row_stride_c = 10, col_stride_c = 12, start_row_c = +// 4 and start_col_c = 5, then if A = 2x3 and B = 2x4, we get +// +// ------------ +// ------------ +// ------------ +// ------------ +// -----xxxx--- +// -----xxxx--- +// -----xxxx--- +// ------------ +// ------------ +// ------------ +// +template<int kRowA, int kColA, int kRowB, int kColB, int kOperation> +inline void MatrixTransposeMatrixMultiplyEigen(const double* A, + const int num_row_a, + const int num_col_a, + const double* B, + const int num_row_b, + const int num_col_b, + double* C, + const int start_row_c, + const int start_col_c, + const int row_stride_c, + const int col_stride_c) { + const typename EigenTypes<kRowA, kColA>::ConstMatrixRef Aref(A, num_row_a, num_col_a); + const typename EigenTypes<kRowB, kColB>::ConstMatrixRef Bref(B, num_row_b, num_col_b); + MatrixRef Cref(C, row_stride_c, col_stride_c); + Eigen::Block<MatrixRef, kColA, kColB> block(Cref, + start_row_c, start_col_c, + num_col_a, num_col_b); + if (kOperation > 0) { + block CERES_MAYBE_NOALIAS += Aref.transpose() * Bref; + } else if (kOperation < 0) { + block CERES_MAYBE_NOALIAS -= Aref.transpose() * Bref; + } else { + block CERES_MAYBE_NOALIAS = Aref.transpose() * Bref; + } +} + +template<int kRowA, int kColA, int kRowB, int kColB, int kOperation> +inline void MatrixTransposeMatrixMultiplyNaive(const double* A, + const int num_row_a, + const int num_col_a, + const double* B, + const int num_row_b, + const int num_col_b, + double* C, + const int start_row_c, + const int start_col_c, + const int row_stride_c, + const int col_stride_c) { + DCHECK_GT(num_row_a, 0); + DCHECK_GT(num_col_a, 0); + DCHECK_GT(num_row_b, 0); + DCHECK_GT(num_col_b, 0); + DCHECK_GE(start_row_c, 0); + DCHECK_GE(start_col_c, 0); + DCHECK_GT(row_stride_c, 0); + DCHECK_GT(col_stride_c, 0); + + DCHECK((kRowA == Eigen::Dynamic) || (kRowA == num_row_a)); + DCHECK((kColA == Eigen::Dynamic) || (kColA == num_col_a)); + DCHECK((kRowB == Eigen::Dynamic) || (kRowB == num_row_b)); + DCHECK((kColB == Eigen::Dynamic) || (kColB == num_col_b)); + + const int NUM_ROW_A = (kRowA != Eigen::Dynamic ? kRowA : num_row_a); + const int NUM_COL_A = (kColA != Eigen::Dynamic ? kColA : num_col_a); + const int NUM_ROW_B = (kColB != Eigen::Dynamic ? kRowB : num_row_b); + const int NUM_COL_B = (kColB != Eigen::Dynamic ? kColB : num_col_b); + DCHECK_EQ(NUM_ROW_A, NUM_ROW_B); + + const int NUM_ROW_C = NUM_COL_A; + const int NUM_COL_C = NUM_COL_B; + DCHECK_LT(start_row_c + NUM_ROW_C, row_stride_c); + DCHECK_LT(start_col_c + NUM_COL_C, col_stride_c); + + for (int row = 0; row < NUM_ROW_C; ++row) { + for (int col = 0; col < NUM_COL_C; ++col) { + double tmp = 0.0; + for (int k = 0; k < NUM_ROW_A; ++k) { + tmp += A[k * NUM_COL_A + row] * B[k * NUM_COL_B + col]; + } + + const int index = (row + start_row_c) * col_stride_c + start_col_c + col; + if (kOperation > 0) { + C[index]+= tmp; + } else if (kOperation < 0) { + C[index]-= tmp; + } else { + C[index]= tmp; + } + } + } +} + +template<int kRowA, int kColA, int kRowB, int kColB, int kOperation> +inline void MatrixTransposeMatrixMultiply(const double* A, + const int num_row_a, + const int num_col_a, + const double* B, + const int num_row_b, + const int num_col_b, + double* C, + const int start_row_c, + const int start_col_c, + const int row_stride_c, + const int col_stride_c) { +#ifdef CERES_NO_CUSTOM_BLAS + MatrixTransposeMatrixMultiplyEigen<kRowA, kColA, kRowB, kColB, kOperation>( + A, num_row_a, num_col_a, + B, num_row_b, num_col_b, + C, start_row_c, start_col_c, row_stride_c, col_stride_c); + return; + +#else + + if (kRowA != Eigen::Dynamic && kColA != Eigen::Dynamic && + kRowB != Eigen::Dynamic && kColB != Eigen::Dynamic) { + MatrixTransposeMatrixMultiplyEigen<kRowA, kColA, kRowB, kColB, kOperation>( + A, num_row_a, num_col_a, + B, num_row_b, num_col_b, + C, start_row_c, start_col_c, row_stride_c, col_stride_c); + } else { + MatrixTransposeMatrixMultiplyNaive<kRowA, kColA, kRowB, kColB, kOperation>( + A, num_row_a, num_col_a, + B, num_row_b, num_col_b, + C, start_row_c, start_col_c, row_stride_c, col_stride_c); + } + +#endif +} + +template<int kRowA, int kColA, int kOperation> +inline void MatrixVectorMultiply(const double* A, + const int num_row_a, + const int num_col_a, + const double* b, + double* c) { +#ifdef CERES_NO_CUSTOM_BLAS + const typename EigenTypes<kRowA, kColA>::ConstMatrixRef Aref(A, num_row_a, num_col_a); + const typename EigenTypes<kColA>::ConstVectorRef bref(b, num_col_a); + typename EigenTypes<kRowA>::VectorRef cref(c, num_row_a); + + // lazyProduct works better than .noalias() for matrix-vector + // products. + if (kOperation > 0) { + cref += Aref.lazyProduct(bref); + } else if (kOperation < 0) { + cref -= Aref.lazyProduct(bref); + } else { + cref -= Aref.lazyProduct(bref); + } +#else + + DCHECK_GT(num_row_a, 0); + DCHECK_GT(num_col_a, 0); + DCHECK((kRowA == Eigen::Dynamic) || (kRowA == num_row_a)); + DCHECK((kColA == Eigen::Dynamic) || (kColA == num_col_a)); + + const int NUM_ROW_A = (kRowA != Eigen::Dynamic ? kRowA : num_row_a); + const int NUM_COL_A = (kColA != Eigen::Dynamic ? kColA : num_col_a); + + for (int row = 0; row < NUM_ROW_A; ++row) { + double tmp = 0.0; + for (int col = 0; col < NUM_COL_A; ++col) { + tmp += A[row * NUM_COL_A + col] * b[col]; + } + + if (kOperation > 0) { + c[row] += tmp; + } else if (kOperation < 0) { + c[row] -= tmp; + } else { + c[row] = tmp; + } + } +#endif // CERES_NO_CUSTOM_BLAS +} + +// c op A' * b; +// +// where op can be +=, -=, or =. +// +// The template parameters (kRowA, kColA) allow specialization of the +// loop at compile time. If this information is not available, then +// Eigen::Dynamic should be used as the template argument. +// +// kOperation = 1 -> c += A' * b +// kOperation = -1 -> c -= A' * b +// kOperation = 0 -> c = A' * b +template<int kRowA, int kColA, int kOperation> +inline void MatrixTransposeVectorMultiply(const double* A, + const int num_row_a, + const int num_col_a, + const double* b, + double* c) { +#ifdef CERES_NO_CUSTOM_BLAS + const typename EigenTypes<kRowA, kColA>::ConstMatrixRef Aref(A, num_row_a, num_col_a); + const typename EigenTypes<kRowA>::ConstVectorRef bref(b, num_row_a); + typename EigenTypes<kColA>::VectorRef cref(c, num_col_a); + + // lazyProduct works better than .noalias() for matrix-vector + // products. + if (kOperation > 0) { + cref += Aref.transpose().lazyProduct(bref); + } else if (kOperation < 0) { + cref -= Aref.transpose().lazyProduct(bref); + } else { + cref -= Aref.transpose().lazyProduct(bref); + } +#else + + DCHECK_GT(num_row_a, 0); + DCHECK_GT(num_col_a, 0); + DCHECK((kRowA == Eigen::Dynamic) || (kRowA == num_row_a)); + DCHECK((kColA == Eigen::Dynamic) || (kColA == num_col_a)); + + const int NUM_ROW_A = (kRowA != Eigen::Dynamic ? kRowA : num_row_a); + const int NUM_COL_A = (kColA != Eigen::Dynamic ? kColA : num_col_a); + + for (int row = 0; row < NUM_COL_A; ++row) { + double tmp = 0.0; + for (int col = 0; col < NUM_ROW_A; ++col) { + tmp += A[col * NUM_COL_A + row] * b[col]; + } + + if (kOperation > 0) { + c[row] += tmp; + } else if (kOperation < 0) { + c[row] -= tmp; + } else { + c[row] = tmp; + } + } +#endif // CERES_NO_CUSTOM_BLAS +} + +#undef CERES_MAYBE_NOALIAS + +} // namespace internal +} // namespace ceres + +#endif // CERES_INTERNAL_BLAS_H_ diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc index dbe5ec93ef0..ab6fcef1945 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/block_sparse_matrix.cc @@ -33,6 +33,7 @@ #include <cstddef> #include <algorithm> #include <vector> +#include "ceres/blas.h" #include "ceres/block_structure.h" #include "ceres/internal/eigen.h" #include "ceres/matrix_proto.h" @@ -117,16 +118,15 @@ void BlockSparseMatrix::RightMultiply(const double* x, double* y) const { for (int i = 0; i < block_structure_->rows.size(); ++i) { int row_block_pos = block_structure_->rows[i].block.position; int row_block_size = block_structure_->rows[i].block.size; - VectorRef yref(y + row_block_pos, row_block_size); const vector<Cell>& cells = block_structure_->rows[i].cells; for (int j = 0; j < cells.size(); ++j) { int col_block_id = cells[j].block_id; int col_block_size = block_structure_->cols[col_block_id].size; int col_block_pos = block_structure_->cols[col_block_id].position; - ConstVectorRef xref(x + col_block_pos, col_block_size); - MatrixRef m(values_.get() + cells[j].position, - row_block_size, col_block_size); - yref += m.lazyProduct(xref); + MatrixVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>( + values_.get() + cells[j].position, row_block_size, col_block_size, + x + col_block_pos, + y + row_block_pos); } } } @@ -138,16 +138,16 @@ void BlockSparseMatrix::LeftMultiply(const double* x, double* y) const { for (int i = 0; i < block_structure_->rows.size(); ++i) { int row_block_pos = block_structure_->rows[i].block.position; int row_block_size = block_structure_->rows[i].block.size; - const ConstVectorRef xref(x + row_block_pos, row_block_size); const vector<Cell>& cells = block_structure_->rows[i].cells; for (int j = 0; j < cells.size(); ++j) { int col_block_id = cells[j].block_id; int col_block_size = block_structure_->cols[col_block_id].size; int col_block_pos = block_structure_->cols[col_block_id].position; - VectorRef yref(y + col_block_pos, col_block_size); - MatrixRef m(values_.get() + cells[j].position, - row_block_size, col_block_size); - yref += m.transpose().lazyProduct(xref); + MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>( + values_.get() + cells[j].position, row_block_size, col_block_size, + x + row_block_pos, + y + col_block_pos); + } } } diff --git a/extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.cc b/extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.cc index 0722fc82c02..c488184ac93 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/partitioned_matrix_view.cc @@ -35,6 +35,7 @@ #include <algorithm> #include <cstring> #include <vector> +#include "ceres/blas.h" #include "ceres/block_sparse_matrix.h" #include "ceres/block_structure.h" #include "ceres/internal/eigen.h" @@ -103,13 +104,10 @@ void PartitionedMatrixView::RightMultiplyE(const double* x, double* y) const { const int col_block_id = cell.block_id; const int col_block_pos = bs->cols[col_block_id].position; const int col_block_size = bs->cols[col_block_id].size; - - ConstVectorRef xref(x + col_block_pos, col_block_size); - VectorRef yref(y + row_block_pos, row_block_size); - ConstMatrixRef m(row_values + cell.position, - row_block_size, - col_block_size); - yref += m.lazyProduct(xref); + MatrixVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>( + row_values + cell.position, row_block_size, col_block_size, + x + col_block_pos, + y + row_block_pos); } } @@ -124,20 +122,16 @@ void PartitionedMatrixView::RightMultiplyF(const double* x, double* y) const { for (int r = 0; r < bs->rows.size(); ++r) { const int row_block_pos = bs->rows[r].block.position; const int row_block_size = bs->rows[r].block.size; - VectorRef yref(y + row_block_pos, row_block_size); const vector<Cell>& cells = bs->rows[r].cells; for (int c = (r < num_row_blocks_e_) ? 1 : 0; c < cells.size(); ++c) { const double* row_values = matrix_.RowBlockValues(r); const int col_block_id = cells[c].block_id; const int col_block_pos = bs->cols[col_block_id].position; const int col_block_size = bs->cols[col_block_id].size; - - ConstVectorRef xref(x + col_block_pos - num_cols_e(), - col_block_size); - ConstMatrixRef m(row_values + cells[c].position, - row_block_size, - col_block_size); - yref += m.lazyProduct(xref); + MatrixVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>( + row_values + cells[c].position, row_block_size, col_block_size, + x + col_block_pos - num_cols_e(), + y + row_block_pos); } } } @@ -155,13 +149,10 @@ void PartitionedMatrixView::LeftMultiplyE(const double* x, double* y) const { const int col_block_id = cell.block_id; const int col_block_pos = bs->cols[col_block_id].position; const int col_block_size = bs->cols[col_block_id].size; - - ConstVectorRef xref(x + row_block_pos, row_block_size); - VectorRef yref(y + col_block_pos, col_block_size); - ConstMatrixRef m(row_values + cell.position, - row_block_size, - col_block_size); - yref += m.transpose().lazyProduct(xref); + MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>( + row_values + cell.position, row_block_size, col_block_size, + x + row_block_pos, + y + col_block_pos); } } @@ -176,19 +167,16 @@ void PartitionedMatrixView::LeftMultiplyF(const double* x, double* y) const { for (int r = 0; r < bs->rows.size(); ++r) { const int row_block_pos = bs->rows[r].block.position; const int row_block_size = bs->rows[r].block.size; - ConstVectorRef xref(x + row_block_pos, row_block_size); const vector<Cell>& cells = bs->rows[r].cells; for (int c = (r < num_row_blocks_e_) ? 1 : 0; c < cells.size(); ++c) { const double* row_values = matrix_.RowBlockValues(r); const int col_block_id = cells[c].block_id; const int col_block_pos = bs->cols[col_block_id].position; const int col_block_size = bs->cols[col_block_id].size; - - VectorRef yref(y + col_block_pos - num_cols_e(), col_block_size); - ConstMatrixRef m(row_values + cells[c].position, - row_block_size, - col_block_size); - yref += m.transpose().lazyProduct(xref); + MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>( + row_values + cells[c].position, row_block_size, col_block_size, + x + row_block_pos, + y + col_block_pos - num_cols_e()); } } } @@ -267,15 +255,15 @@ void PartitionedMatrixView::UpdateBlockDiagonalEtE( const int row_block_size = bs->rows[r].block.size; const int block_id = cell.block_id; const int col_block_size = bs->cols[block_id].size; - ConstMatrixRef m(row_values + cell.position, - row_block_size, - col_block_size); - const int cell_position = block_diagonal_structure->rows[block_id].cells[0].position; - MatrixRef(block_diagonal->mutable_values() + cell_position, - col_block_size, col_block_size).noalias() += m.transpose() * m; + MatrixTransposeMatrixMultiply + <Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>( + row_values + cell.position, row_block_size, col_block_size, + row_values + cell.position, row_block_size, col_block_size, + block_diagonal->mutable_values() + cell_position, + 0, 0, col_block_size, col_block_size); } } @@ -298,15 +286,16 @@ void PartitionedMatrixView::UpdateBlockDiagonalFtF( for (int c = (r < num_row_blocks_e_) ? 1 : 0; c < cells.size(); ++c) { const int col_block_id = cells[c].block_id; const int col_block_size = bs->cols[col_block_id].size; - ConstMatrixRef m(row_values + cells[c].position, - row_block_size, - col_block_size); const int diagonal_block_id = col_block_id - num_col_blocks_e_; const int cell_position = block_diagonal_structure->rows[diagonal_block_id].cells[0].position; - MatrixRef(block_diagonal->mutable_values() + cell_position, - col_block_size, col_block_size).noalias() += m.transpose() * m; + MatrixTransposeMatrixMultiply + <Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>( + row_values + cells[c].position, row_block_size, col_block_size, + row_values + cells[c].position, row_block_size, col_block_size, + block_diagonal->mutable_values() + cell_position, + 0, 0, col_block_size, col_block_size); } } } diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc index e1be4e2a78a..875f4551044 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc @@ -291,14 +291,8 @@ bool SparseSchurComplementSolver::SolveReducedLinearSystemUsingSuiteSparse( } else { factor_ = ss_.AnalyzeCholesky(cholmod_lhs); } - - if (VLOG_IS_ON(2)) { - cholmod_print_common(const_cast<char*>("Symbolic Analysis"), ss_.mutable_cc()); - } } - CHECK_NOTNULL(factor_); - cholmod_dense* cholmod_solution = ss_.SolveCholesky(cholmod_lhs, factor_, cholmod_rhs); diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h index 877621bb48c..e0c7fdafcb6 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h +++ b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator.h @@ -321,9 +321,25 @@ class SchurEliminator : public SchurEliminatorBase { // see the documentation of the Chunk object above. vector<Chunk> chunks_; + // TODO(sameeragarwal): The following two arrays contain per-thread + // storage. They should be refactored into a per thread struct. + // Buffer to store the products of the y and z blocks generated - // during the elimination phase. + // during the elimination phase. buffer_ is of size num_threads * + // buffer_size_. Each thread accesses the chunk + // + // [thread_id * buffer_size_ , (thread_id + 1) * buffer_size_] + // scoped_array<double> buffer_; + + // Buffer to store per thread matrix matrix products used by + // ChunkOuterProduct. Like buffer_ it is of size num_threads * + // buffer_size_. Each thread accesses the chunk + // + // [thread_id * buffer_size_ , (thread_id + 1) * buffer_size_] + // + scoped_array<double> chunk_outer_product_buffer_; + int buffer_size_; int num_threads_; int uneliminated_row_begins_; diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h index 339c44bc41c..b46eab92c34 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h +++ b/extern/libmv/third_party/ceres/internal/ceres/schur_eliminator_impl.h @@ -34,10 +34,6 @@ #ifndef CERES_INTERNAL_SCHUR_ELIMINATOR_IMPL_H_ #define CERES_INTERNAL_SCHUR_ELIMINATOR_IMPL_H_ -#ifdef CERES_USE_OPENMP -#include <omp.h> -#endif - // Eigen has an internal threshold switching between different matrix // multiplication algorithms. In particular for matrices larger than // EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD it uses a cache friendly @@ -46,19 +42,25 @@ // are thin and long, the default choice may not be optimal. This is // the case for us, as the default choice causes a 30% performance // regression when we moved from Eigen2 to Eigen3. + #define EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD 10 +#ifdef CERES_USE_OPENMP +#include <omp.h> +#endif + #include <algorithm> #include <map> #include "Eigen/Dense" +#include "ceres/blas.h" #include "ceres/block_random_access_matrix.h" #include "ceres/block_sparse_matrix.h" #include "ceres/block_structure.h" +#include "ceres/internal/eigen.h" +#include "ceres/internal/scoped_ptr.h" #include "ceres/map_util.h" #include "ceres/schur_eliminator.h" #include "ceres/stl_util.h" -#include "ceres/internal/eigen.h" -#include "ceres/internal/scoped_ptr.h" #include "glog/logging.h" namespace ceres { @@ -149,13 +151,16 @@ Init(int num_eliminate_blocks, const CompressedRowBlockStructure* bs) { buffer_.reset(new double[buffer_size_ * num_threads_]); + // chunk_outer_product_buffer_ only needs to store e_block_size * + // f_block_size, which is always less than buffer_size_, so we just + // allocate buffer_size_ per thread. + chunk_outer_product_buffer_.reset(new double[buffer_size_ * num_threads_]); + STLDeleteElements(&rhs_locks_); rhs_locks_.resize(num_col_blocks - num_eliminate_blocks_); for (int i = 0; i < num_col_blocks - num_eliminate_blocks_; ++i) { rhs_locks_[i] = new Mutex; } - - VLOG(1) << "Eliminator threads: " << num_threads_; } template <int kRowBlockSize, int kEBlockSize, int kFBlockSize> @@ -261,7 +266,7 @@ Eliminate(const BlockSparseMatrixBase* A, typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix inverse_ete = ete .template selfadjointView<Eigen::Upper>() - .ldlt() + .llt() .solve(Matrix::Identity(e_block_size, e_block_size)); // For the current chunk compute and update the rhs of the reduced @@ -294,8 +299,8 @@ BackSubstitute(const BlockSparseMatrixBase* A, const int e_block_id = bs->rows[chunk.start].cells.front().block_id; const int e_block_size = bs->cols[e_block_id].size; - typename EigenTypes<kEBlockSize>::VectorRef y_block( - y + bs->cols[e_block_id].position, e_block_size); + double* y_ptr = y + bs->cols[e_block_id].position; + typename EigenTypes<kEBlockSize>::VectorRef y_block(y_ptr, e_block_size); typename EigenTypes<kEBlockSize, kEBlockSize>::Matrix ete(e_block_size, e_block_size); @@ -312,40 +317,35 @@ BackSubstitute(const BlockSparseMatrixBase* A, const double* row_values = A->RowBlockValues(chunk.start + j); const Cell& e_cell = row.cells.front(); DCHECK_EQ(e_block_id, e_cell.block_id); - const typename EigenTypes<kRowBlockSize, kEBlockSize>::ConstMatrixRef - e_block(row_values + e_cell.position, - row.block.size, - e_block_size); - typename EigenTypes<kRowBlockSize>::Vector - sj = + typename EigenTypes<kRowBlockSize>::Vector sj = typename EigenTypes<kRowBlockSize>::ConstVectorRef - (b + bs->rows[chunk.start + j].block.position, - row.block.size); + (b + bs->rows[chunk.start + j].block.position, row.block.size); for (int c = 1; c < row.cells.size(); ++c) { const int f_block_id = row.cells[c].block_id; const int f_block_size = bs->cols[f_block_id].size; - const typename EigenTypes<kRowBlockSize, kFBlockSize>::ConstMatrixRef - f_block(row_values + row.cells[c].position, - row.block.size, f_block_size); const int r_block = f_block_id - num_eliminate_blocks_; - sj -= f_block * - typename EigenTypes<kFBlockSize>::ConstVectorRef - (z + lhs_row_layout_[r_block], f_block_size); + MatrixVectorMultiply<kRowBlockSize, kFBlockSize, -1>( + row_values + row.cells[c].position, row.block.size, f_block_size, + z + lhs_row_layout_[r_block], + sj.data()); } - y_block += e_block.transpose() * sj; - ete.template selfadjointView<Eigen::Upper>() - .rankUpdate(e_block.transpose(), 1.0); + MatrixTransposeVectorMultiply<kRowBlockSize, kEBlockSize, 1>( + row_values + e_cell.position, row.block.size, e_block_size, + sj.data(), + y_ptr); + + MatrixTransposeMatrixMultiply + <kRowBlockSize, kEBlockSize,kRowBlockSize, kEBlockSize, 1>( + row_values + e_cell.position, row.block.size, e_block_size, + row_values + e_cell.position, row.block.size, e_block_size, + ete.data(), 0, 0, e_block_size, e_block_size); } - y_block = - ete - .template selfadjointView<Eigen::Upper>() - .ldlt() - .solve(y_block); + ete.llt().solveInPlace(y_block); } } @@ -382,15 +382,12 @@ UpdateRhs(const Chunk& chunk, for (int c = 1; c < row.cells.size(); ++c) { const int block_id = row.cells[c].block_id; const int block_size = bs->cols[block_id].size; - const typename EigenTypes<kRowBlockSize, kFBlockSize>::ConstMatrixRef - b(row_values + row.cells[c].position, - row.block.size, block_size); - const int block = block_id - num_eliminate_blocks_; CeresMutexLock l(rhs_locks_[block]); - typename EigenTypes<kFBlockSize>::VectorRef - (rhs + lhs_row_layout_[block], block_size).noalias() - += b.transpose() * sj; + MatrixTransposeVectorMultiply<kRowBlockSize, kFBlockSize, 1>( + row_values + row.cells[c].position, + row.block.size, block_size, + sj.data(), rhs + lhs_row_layout_[block]); } b_pos += row.block.size; } @@ -446,34 +443,31 @@ ChunkDiagonalBlockAndGradient( // Extract the e_block, ETE += E_i' E_i const Cell& e_cell = row.cells.front(); - const typename EigenTypes<kRowBlockSize, kEBlockSize>::ConstMatrixRef - e_block(row_values + e_cell.position, - row.block.size, - e_block_size); - - ete->template selfadjointView<Eigen::Upper>() - .rankUpdate(e_block.transpose(), 1.0); + MatrixTransposeMatrixMultiply + <kRowBlockSize, kEBlockSize, kRowBlockSize, kEBlockSize, 1>( + row_values + e_cell.position, row.block.size, e_block_size, + row_values + e_cell.position, row.block.size, e_block_size, + ete->data(), 0, 0, e_block_size, e_block_size); // g += E_i' b_i - g->noalias() += e_block.transpose() * - typename EigenTypes<kRowBlockSize>::ConstVectorRef - (b + b_pos, row.block.size); + MatrixTransposeVectorMultiply<kRowBlockSize, kEBlockSize, 1>( + row_values + e_cell.position, row.block.size, e_block_size, + b + b_pos, + g->data()); + // buffer = E'F. This computation is done by iterating over the // f_blocks for each row in the chunk. for (int c = 1; c < row.cells.size(); ++c) { const int f_block_id = row.cells[c].block_id; const int f_block_size = bs->cols[f_block_id].size; - const typename EigenTypes<kRowBlockSize, kFBlockSize>::ConstMatrixRef - f_block(row_values + row.cells[c].position, - row.block.size, f_block_size); - double* buffer_ptr = buffer + FindOrDie(chunk.buffer_layout, f_block_id); - - typename EigenTypes<kEBlockSize, kFBlockSize>::MatrixRef - (buffer_ptr, e_block_size, f_block_size).noalias() - += e_block.transpose() * f_block; + MatrixTransposeMatrixMultiply + <kRowBlockSize, kEBlockSize, kRowBlockSize, kFBlockSize, 1>( + row_values + e_cell.position, row.block.size, e_block_size, + row_values + row.cells[c].position, row.block.size, f_block_size, + buffer_ptr, 0, 0, e_block_size, f_block_size); } b_pos += row.block.size; } @@ -497,15 +491,24 @@ ChunkOuterProduct(const CompressedRowBlockStructure* bs, // references to the left hand side. const int e_block_size = inverse_ete.rows(); BufferLayoutType::const_iterator it1 = buffer_layout.begin(); + +#ifdef CERES_USE_OPENMP + int thread_id = omp_get_thread_num(); +#else + int thread_id = 0; +#endif + double* b1_transpose_inverse_ete = + chunk_outer_product_buffer_.get() + thread_id * buffer_size_; + // S(i,j) -= bi' * ete^{-1} b_j for (; it1 != buffer_layout.end(); ++it1) { const int block1 = it1->first - num_eliminate_blocks_; const int block1_size = bs->cols[it1->first].size; - - const typename EigenTypes<kEBlockSize, kFBlockSize>::ConstMatrixRef - b1(buffer + it1->second, e_block_size, block1_size); - const typename EigenTypes<kFBlockSize, kEBlockSize>::Matrix - b1_transpose_inverse_ete = b1.transpose() * inverse_ete; + MatrixTransposeMatrixMultiply + <kEBlockSize, kFBlockSize, kEBlockSize, kEBlockSize, 0>( + buffer + it1->second, e_block_size, block1_size, + inverse_ete.data(), e_block_size, e_block_size, + b1_transpose_inverse_ete, 0, 0, block1_size, e_block_size); BufferLayoutType::const_iterator it2 = it1; for (; it2 != buffer_layout.end(); ++it2) { @@ -515,46 +518,15 @@ ChunkOuterProduct(const CompressedRowBlockStructure* bs, CellInfo* cell_info = lhs->GetCell(block1, block2, &r, &c, &row_stride, &col_stride); - if (cell_info == NULL) { - continue; + if (cell_info != NULL) { + const int block2_size = bs->cols[it2->first].size; + CeresMutexLock l(&cell_info->m); + MatrixMatrixMultiply + <kFBlockSize, kEBlockSize, kEBlockSize, kFBlockSize, -1>( + b1_transpose_inverse_ete, block1_size, e_block_size, + buffer + it2->second, e_block_size, block2_size, + cell_info->values, r, c, row_stride, col_stride); } - - const int block2_size = bs->cols[it2->first].size; - const typename EigenTypes<kEBlockSize, kFBlockSize>::ConstMatrixRef - b2(buffer + it2->second, e_block_size, block2_size); - - CeresMutexLock l(&cell_info->m); - MatrixRef m(cell_info->values, row_stride, col_stride); - - // We explicitly construct a block object here instead of using - // m.block(), as m.block() variant of the constructor does not - // allow mixing of template sizing and runtime sizing parameters - // like the Matrix class does. - Eigen::Block<MatrixRef, kFBlockSize, kFBlockSize> - block(m, r, c, block1_size, block2_size); -#ifdef CERES_WORK_AROUND_ANDROID_NDK_COMPILER_BUG - // Removing the ".noalias()" annotation on the following statement is - // necessary to produce a correct build with the Android NDK, including - // versions 6, 7, 8, and 8b, when built with STLPort and the - // non-standalone toolchain (i.e. ndk-build). This appears to be a - // compiler bug; if the workaround is not in place, the line - // - // block.noalias() -= b1_transpose_inverse_ete * b2; - // - // gets compiled to - // - // block.noalias() += b1_transpose_inverse_ete * b2; - // - // which breaks schur elimination. Introducing a temporary by removing the - // .noalias() annotation causes the issue to disappear. Tracking this - // issue down was tricky, since the test suite doesn't run when built with - // the non-standalone toolchain. - // - // TODO(keir): Make a reproduction case for this and send it upstream. - block -= b1_transpose_inverse_ete * b2; -#else - block.noalias() -= b1_transpose_inverse_ete * b2; -#endif // CERES_WORK_AROUND_ANDROID_NDK_COMPILER_BUG } } } @@ -624,10 +596,13 @@ NoEBlockRowOuterProduct(const BlockSparseMatrixBase* A, &row_stride, &col_stride); if (cell_info != NULL) { CeresMutexLock l(&cell_info->m); - MatrixRef m(cell_info->values, row_stride, col_stride); - m.block(r, c, block1_size, block1_size) - .selfadjointView<Eigen::Upper>() - .rankUpdate(b1.transpose(), 1.0); + // This multiply currently ignores the fact that this is a + // symmetric outer product. + MatrixTransposeMatrixMultiply + <Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>( + row_values + row.cells[i].position, row.block.size, block1_size, + row_values + row.cells[i].position, row.block.size, block1_size, + cell_info->values, r, c, row_stride, col_stride); } for (int j = i + 1; j < row.cells.size(); ++j) { @@ -638,17 +613,15 @@ NoEBlockRowOuterProduct(const BlockSparseMatrixBase* A, CellInfo* cell_info = lhs->GetCell(block1, block2, &r, &c, &row_stride, &col_stride); - if (cell_info == NULL) { - continue; + if (cell_info != NULL) { + const int block2_size = bs->cols[row.cells[j].block_id].size; + CeresMutexLock l(&cell_info->m); + MatrixTransposeMatrixMultiply + <Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, Eigen::Dynamic, 1>( + row_values + row.cells[i].position, row.block.size, block1_size, + row_values + row.cells[j].position, row.block.size, block2_size, + cell_info->values, r, c, row_stride, col_stride); } - - const int block2_size = bs->cols[row.cells[j].block_id].size; - CeresMutexLock l(&cell_info->m); - MatrixRef m(cell_info->values, row_stride, col_stride); - m.block(r, c, block1_size, block2_size).noalias() += - b1.transpose() * ConstMatrixRef(row_values + row.cells[j].position, - row.block.size, - block2_size); } } } @@ -670,25 +643,18 @@ EBlockRowOuterProduct(const BlockSparseMatrixBase* A, DCHECK_GE(block1, 0); const int block1_size = bs->cols[row.cells[i].block_id].size; - const typename EigenTypes<kRowBlockSize, kFBlockSize>::ConstMatrixRef - b1(row_values + row.cells[i].position, - row.block.size, block1_size); - { - int r, c, row_stride, col_stride; - CellInfo* cell_info = lhs->GetCell(block1, block1, - &r, &c, - &row_stride, &col_stride); - if (cell_info == NULL) { - continue; - } - + int r, c, row_stride, col_stride; + CellInfo* cell_info = lhs->GetCell(block1, block1, + &r, &c, + &row_stride, &col_stride); + if (cell_info != NULL) { CeresMutexLock l(&cell_info->m); - MatrixRef m(cell_info->values, row_stride, col_stride); - - Eigen::Block<MatrixRef, kFBlockSize, kFBlockSize> - block(m, r, c, block1_size, block1_size); - block.template selfadjointView<Eigen::Upper>() - .rankUpdate(b1.transpose(), 1.0); + // block += b1.transpose() * b1; + MatrixTransposeMatrixMultiply + <kRowBlockSize, kFBlockSize, kRowBlockSize, kFBlockSize, 1>( + row_values + row.cells[i].position, row.block.size, block1_size, + row_values + row.cells[i].position, row.block.size, block1_size, + cell_info->values, r, c, row_stride, col_stride); } for (int j = i + 1; j < row.cells.size(); ++j) { @@ -700,20 +666,14 @@ EBlockRowOuterProduct(const BlockSparseMatrixBase* A, CellInfo* cell_info = lhs->GetCell(block1, block2, &r, &c, &row_stride, &col_stride); - if (cell_info == NULL) { - continue; + if (cell_info != NULL) { + // block += b1.transpose() * b2; + MatrixTransposeMatrixMultiply + <kRowBlockSize, kFBlockSize, kRowBlockSize, kFBlockSize, 1>( + row_values + row.cells[i].position, row.block.size, block1_size, + row_values + row.cells[j].position, row.block.size, block2_size, + cell_info->values, r, c, row_stride, col_stride); } - - const typename EigenTypes<kRowBlockSize, kFBlockSize>::ConstMatrixRef - b2(row_values + row.cells[j].position, - row.block.size, - block2_size); - - CeresMutexLock l(&cell_info->m); - MatrixRef m(cell_info->values, row_stride, col_stride); - Eigen::Block<MatrixRef, kFBlockSize, kFBlockSize> - block(m, r, c, block1_size, block2_size); - block.noalias() += b1.transpose() * b2; } } } diff --git a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc index 195cacb984c..aacba86e64a 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc @@ -213,13 +213,7 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse( } else { factor_ = ss_.AnalyzeCholesky(lhs.get()); } - - if (VLOG_IS_ON(2)) { - cholmod_print_common(const_cast<char*>("Symbolic Analysis"), ss_.mutable_cc()); - } } - - CHECK_NOTNULL(factor_); event_logger.AddEvent("Analysis"); cholmod_dense* sol = ss_.SolveCholesky(lhs.get(), factor_, rhs); diff --git a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc index d200aeb82f3..87fae75287e 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.cc @@ -35,8 +35,18 @@ #include "cholmod.h" #include "ceres/compressed_row_sparse_matrix.h" #include "ceres/triplet_sparse_matrix.h" + namespace ceres { namespace internal { + +SuiteSparse::SuiteSparse() { + cholmod_start(&cc_); +} + +SuiteSparse::~SuiteSparse() { + cholmod_finish(&cc_); +} + cholmod_sparse* SuiteSparse::CreateSparseMatrix(TripletSparseMatrix* A) { cholmod_triplet triplet; @@ -117,10 +127,16 @@ cholmod_factor* SuiteSparse::AnalyzeCholesky(cholmod_sparse* A) { cc_.nmethods = 1; cc_.method[0].ordering = CHOLMOD_AMD; cc_.supernodal = CHOLMOD_AUTO; + cholmod_factor* factor = cholmod_analyze(A, &cc_); CHECK_EQ(cc_.status, CHOLMOD_OK) << "Cholmod symbolic analysis failed " << cc_.status; CHECK_NOTNULL(factor); + + if (VLOG_IS_ON(2)) { + cholmod_print_common(const_cast<char*>("Symbolic Analysis"), &cc_); + } + return factor; } @@ -139,13 +155,20 @@ cholmod_factor* SuiteSparse::AnalyzeCholeskyWithUserOrdering( cholmod_sparse* A, const vector<int>& ordering) { CHECK_EQ(ordering.size(), A->nrow); + cc_.nmethods = 1; cc_.method[0].ordering = CHOLMOD_GIVEN; + cholmod_factor* factor = cholmod_analyze_p(A, const_cast<int*>(&ordering[0]), NULL, 0, &cc_); CHECK_EQ(cc_.status, CHOLMOD_OK) << "Cholmod symbolic analysis failed " << cc_.status; CHECK_NOTNULL(factor); + + if (VLOG_IS_ON(2)) { + cholmod_print_common(const_cast<char*>("Symbolic Analysis"), &cc_); + } + return factor; } @@ -276,36 +299,52 @@ bool SuiteSparse::Cholesky(cholmod_sparse* A, cholmod_factor* L) { CHECK_NOTNULL(A); CHECK_NOTNULL(L); + // Save the current print level and silence CHOLMOD, otherwise + // CHOLMOD is prone to dumping stuff to stderr, which can be + // distracting when the error (matrix is indefinite) is not a fatal + // failure. + const int old_print_level = cc_.print; + cc_.print = 0; + cc_.quick_return_if_not_posdef = 1; int status = cholmod_factorize(A, L, &cc_); + cc_.print = old_print_level; + + // TODO(sameeragarwal): This switch statement is not consistent. It + // treats all kinds of CHOLMOD failures as warnings. Some of these + // like out of memory are definitely not warnings. The problem is + // that the return value Cholesky is two valued, but the state of + // the linear solver is really three valued. SUCCESS, + // NON_FATAL_FAILURE (e.g., indefinite matrix) and FATAL_FAILURE + // (e.g. out of memory). switch (cc_.status) { case CHOLMOD_NOT_INSTALLED: - LOG(WARNING) << "Cholmod failure: method not installed."; + LOG(WARNING) << "CHOLMOD failure: Method not installed."; return false; case CHOLMOD_OUT_OF_MEMORY: - LOG(WARNING) << "Cholmod failure: out of memory."; + LOG(WARNING) << "CHOLMOD failure: Out of memory."; return false; case CHOLMOD_TOO_LARGE: - LOG(WARNING) << "Cholmod failure: integer overflow occured."; + LOG(WARNING) << "CHOLMOD failure: Integer overflow occured."; return false; case CHOLMOD_INVALID: - LOG(WARNING) << "Cholmod failure: invalid input."; + LOG(WARNING) << "CHOLMOD failure: Invalid input."; return false; case CHOLMOD_NOT_POSDEF: // TODO(sameeragarwal): These two warnings require more // sophisticated handling going forward. For now we will be // strict and treat them as failures. - LOG(WARNING) << "Cholmod warning: matrix not positive definite."; + LOG(WARNING) << "CHOLMOD warning: Matrix not positive definite."; return false; case CHOLMOD_DSMALL: - LOG(WARNING) << "Cholmod warning: D for LDL' or diag(L) or " + LOG(WARNING) << "CHOLMOD warning: D for LDL' or diag(L) or " << "LL' has tiny absolute value."; return false; case CHOLMOD_OK: if (status != 0) { return true; } - LOG(WARNING) << "Cholmod failure: cholmod_factorize returned zero " + LOG(WARNING) << "CHOLMOD failure: cholmod_factorize returned zero " << "but cholmod_common::status is CHOLMOD_OK." << "Please report this to ceres-solver@googlegroups.com."; return false; diff --git a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h index 3fe79080d5d..5a8ef63bd2b 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h +++ b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h @@ -56,8 +56,8 @@ class TripletSparseMatrix; // for all cholmod function calls. class SuiteSparse { public: - SuiteSparse() { cholmod_start(&cc_); } - ~SuiteSparse() { cholmod_finish(&cc_); } + SuiteSparse(); + ~SuiteSparse(); // Functions for building cholmod_sparse objects from sparse // matrices stored in triplet form. The matrix A is not diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc index 1678d0072e5..f5c46bfcc68 100644 --- a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc +++ b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc @@ -426,14 +426,8 @@ bool VisibilityBasedPreconditioner::Factorize() { } else { factor_ = ss_.AnalyzeCholesky(lhs); } - - if (VLOG_IS_ON(2)) { - cholmod_print_common(const_cast<char*>("Symbolic Analysis"), ss_.mutable_cc()); - } } - CHECK_NOTNULL(factor_); - bool status = ss_.Cholesky(lhs, factor_); ss_.Free(lhs); return status; diff --git a/extern/libmv/third_party/fast/fast_10.c b/extern/libmv/third_party/fast/fast_10.c index 3af63869478..7929a653a12 100644 --- a/extern/libmv/third_party/fast/fast_10.c +++ b/extern/libmv/third_party/fast/fast_10.c @@ -1,8 +1,7 @@ /*This is mechanically generated code*/ #include <stdlib.h> -typedef struct { int x, y; } xy; -typedef unsigned char byte; +#include "fast.h" int fast10_corner_score(const byte* p, const int pixel[], int bstart) { diff --git a/extern/libmv/third_party/fast/fast_11.c b/extern/libmv/third_party/fast/fast_11.c index b4af4309521..589ddb169f1 100644 --- a/extern/libmv/third_party/fast/fast_11.c +++ b/extern/libmv/third_party/fast/fast_11.c @@ -1,8 +1,7 @@ /*This is mechanically generated code*/ #include <stdlib.h> -typedef struct { int x, y; } xy; -typedef unsigned char byte; +#include "fast.h" int fast11_corner_score(const byte* p, const int pixel[], int bstart) { diff --git a/extern/libmv/third_party/fast/fast_12.c b/extern/libmv/third_party/fast/fast_12.c index f73f68dd043..27426f8c0d8 100644 --- a/extern/libmv/third_party/fast/fast_12.c +++ b/extern/libmv/third_party/fast/fast_12.c @@ -1,8 +1,7 @@ /*This is mechanically generated code*/ #include <stdlib.h> -typedef struct { int x, y; } xy; -typedef unsigned char byte; +#include "fast.h" int fast12_corner_score(const byte* p, const int pixel[], int bstart) { diff --git a/extern/libmv/third_party/fast/fast_9.c b/extern/libmv/third_party/fast/fast_9.c index 6d33daeffbb..c22c1c0e6a0 100644 --- a/extern/libmv/third_party/fast/fast_9.c +++ b/extern/libmv/third_party/fast/fast_9.c @@ -1,8 +1,7 @@ /*This is mechanically generated code*/ #include <stdlib.h> -typedef struct { int x, y; } xy; -typedef unsigned char byte; +#include "fast.h" int fast9_corner_score(const byte* p, const int pixel[], int bstart) { diff --git a/extern/libmv/third_party/gflags/gflags_completions.cc b/extern/libmv/third_party/gflags/gflags_completions.cc index 75e9236ef63..f46a2e0814e 100644 --- a/extern/libmv/third_party/gflags/gflags_completions.cc +++ b/extern/libmv/third_party/gflags/gflags_completions.cc @@ -57,6 +57,7 @@ #include <utility> #include <vector> +#include "gflags/gflags_completions.h" #include "gflags/gflags.h" #include "util.h" diff --git a/extern/libmv/third_party/glog/src/logging.cc b/extern/libmv/third_party/glog/src/logging.cc index bf4d85be5b3..f36e14d2ce4 100644 --- a/extern/libmv/third_party/glog/src/logging.cc +++ b/extern/libmv/third_party/glog/src/logging.cc @@ -1464,6 +1464,10 @@ void LogToStderr() { namespace base { namespace internal { +/* Put prototypes here to suppress strict compiler warnings */ +bool GetExitOnDFatal(); +void SetExitOnDFatal(bool value); + bool GetExitOnDFatal() { MutexLock l(&log_mutex); return exit_on_dfatal; diff --git a/extern/libmv/third_party/glog/src/utilities.cc b/extern/libmv/third_party/glog/src/utilities.cc index c9db2b7f7cd..159b094c170 100644 --- a/extern/libmv/third_party/glog/src/utilities.cc +++ b/extern/libmv/third_party/glog/src/utilities.cc @@ -84,7 +84,7 @@ static void DebugWriteToStderr(const char* data, void *) { } } -void DebugWriteToString(const char* data, void *arg) { +static void DebugWriteToString(const char* data, void *arg) { reinterpret_cast<string*>(arg)->append(data); } diff --git a/extern/libmv/third_party/glog/src/vlog_is_on.cc b/extern/libmv/third_party/glog/src/vlog_is_on.cc index 5eefc96324a..4396aa8d066 100644 --- a/extern/libmv/third_party/glog/src/vlog_is_on.cc +++ b/extern/libmv/third_party/glog/src/vlog_is_on.cc @@ -62,6 +62,12 @@ _START_GOOGLE_NAMESPACE_ namespace glog_internal_namespace_ { +// Put protytype here to suppress strict compiler flags +GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern, + size_t patt_len, + const char* str, + size_t str_len); + // Implementation of fnmatch that does not need 0-termination // of arguments and does not allocate any memory, // but we only support "*" and "?" wildcards, not the "[...]" patterns. diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h index 694ef8bd01d..800daf40887 100644 --- a/intern/cycles/kernel/kernel_camera.h +++ b/intern/cycles/kernel/kernel_camera.h @@ -115,10 +115,10 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa float3 Pfocus = ray->D*ft; /* update ray for effect of lens */ - ray->P = make_float3(lensuv.x, lensuv.y, 0.0f); - ray->D = normalize(Pfocus - ray->P); + float3 lensuvw = make_float3(lensuv.x, lensuv.y, 0.0f); - ray->P += Pcamera; + ray->P += lensuvw; + ray->D = normalize(Pfocus - lensuvw); } /* transform ray from camera to world */ diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp index cefb6315725..3294f1ebe4c 100644 --- a/intern/cycles/render/osl.cpp +++ b/intern/cycles/render/osl.cpp @@ -41,6 +41,12 @@ CCL_NAMESPACE_BEGIN #ifdef WITH_OSL +/* Shared Texture System */ + +OSL::TextureSystem *OSLShaderManager::ts_shared = NULL; +int OSLShaderManager::ts_shared_users = 0; +thread_mutex OSLShaderManager::ts_shared_mutex; + /* Shader Manager */ OSLShaderManager::OSLShaderManager() @@ -54,7 +60,17 @@ OSLShaderManager::OSLShaderManager() OSLShaderManager::~OSLShaderManager() { OSL::ShadingSystem::destroy(ss); - OSL::TextureSystem::destroy(ts); + + /* shared texture system decrease users and destroy if no longer used */ + { + thread_scoped_lock lock(ts_shared_mutex); + ts_shared_users--; + + if(ts_shared_users == 0) { + OSL::TextureSystem::destroy(ts_shared); + ts_shared = NULL; + } + } delete services; } @@ -133,14 +149,22 @@ void OSLShaderManager::device_free(Device *device, DeviceScene *dscene, Scene *s void OSLShaderManager::texture_system_init() { - /* if we let OSL create it, it leaks */ - ts = TextureSystem::create(true); - ts->attribute("automip", 1); - ts->attribute("autotile", 64); - ts->attribute("gray_to_rgb", 1); + /* create texture system, shared between different renders to reduce memory usage */ + thread_scoped_lock lock(ts_shared_mutex); + + if(ts_shared_users == 0) { + ts_shared = TextureSystem::create(true); + + ts_shared->attribute("automip", 1); + ts_shared->attribute("autotile", 64); + ts_shared->attribute("gray_to_rgb", 1); + + /* effectively unlimited for now, until we support proper mipmap lookups */ + ts_shared->attribute("max_memory_MB", 16384); + } - /* effectively unlimited for now, until we support proper mipmap lookups */ - ts->attribute("max_memory_MB", 16384); + ts = ts_shared; + ts_shared_users++; } void OSLShaderManager::shading_system_init() diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h index 2d3996df0eb..c459f6bfa08 100644 --- a/intern/cycles/render/osl.h +++ b/intern/cycles/render/osl.h @@ -21,6 +21,7 @@ #include "util_set.h" #include "util_string.h" +#include "util_thread.h" #include "shader.h" @@ -92,6 +93,10 @@ protected: OSLRenderServices *services; OSL::ErrorHandler errhandler; map<string, OSLShaderInfo> loaded_shaders; + + static OSL::TextureSystem *ts_shared; + static thread_mutex ts_shared_mutex; + static int ts_shared_users; }; #endif diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc index 9343a13e888..cfa758e9a84 100644 --- a/intern/opencolorio/ocio_impl_glsl.cc +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -60,6 +60,7 @@ typedef struct OCIO_GLSLDrawState { bool lut3d_texture_allocated; /* boolean flag indicating whether * lut texture is allocated */ + bool lut3d_texture_valid; GLuint lut3d_texture; /* OGL texture ID for 3D LUT */ @@ -170,12 +171,12 @@ static OCIO_GLSLDrawState *allocateOpenGLState(void) } /* Ensure LUT texture and array are allocated */ -static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state) +static bool ensureLUT3DAllocated(OCIO_GLSLDrawState *state) { int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE; if (state->lut3d_texture_allocated) - return; + return state->lut3d_texture_valid; glGenTextures(1, &state->lut3d_texture); @@ -188,11 +189,22 @@ static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state) glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + + /* clean glError buffer */ + while (glGetError() != GL_NO_ERROR) {} + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, - 0, GL_RGB,GL_FLOAT, &state->lut3d); + 0, GL_RGB, GL_FLOAT, state->lut3d); state->lut3d_texture_allocated = true; + + /* GL_RGB16F_ARB could be not supported at some drivers + * in this case we could not use GLSL display + */ + state->lut3d_texture_valid = glGetError() == GL_NO_ERROR; + + return state->lut3d_texture_valid; } /** @@ -218,7 +230,12 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRc glGetIntegerv(GL_TEXTURE_2D, &state->last_texture); glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit); - ensureLUT3DAllocated(state); + if (!ensureLUT3DAllocated(state)) { + glActiveTexture(state->last_texture_unit); + glBindTexture(GL_TEXTURE_2D, state->last_texture); + + return false; + } /* Step 1: Create a GPU Shader Description */ GpuShaderDesc shaderDesc; diff --git a/release/scripts/modules/bpy/path.py b/release/scripts/modules/bpy/path.py index 6c91568cbc1..cfc0f474215 100644 --- a/release/scripts/modules/bpy/path.py +++ b/release/scripts/modules/bpy/path.py @@ -48,6 +48,10 @@ from _bpy_path import (extensions_audio, ) +def _getattr_bytes(var, attr): + return var.path_resolve(attr, False).as_bytes() + + def abspath(path, start=None, library=None): """ Returns the absolute path relative to the current blend file @@ -60,13 +64,22 @@ def abspath(path, start=None, library=None): convenience, when the library is not None its path replaces *start*. :type library: :class:`bpy.types.Library` """ - if path.startswith("//"): - if library: - start = _os.path.dirname(abspath(library.filepath)) - return _os.path.join(_os.path.dirname(_bpy.data.filepath) - if start is None else start, - path[2:], - ) + if isinstance(path, bytes): + if path.startswith(b"//"): + if library: + start = _os.path.dirname(abspath(_getattr_bytes(library, "filepath"))) + return _os.path.join(_os.path.dirname(_getattr_bytes(_bpy.data, "filepath")) + if start is None else start, + path[2:], + ) + else: + if path.startswith("//"): + if library: + start = _os.path.dirname(abspath(library.filepath)) + return _os.path.join(_os.path.dirname(_bpy.data.filepath) + if start is None else start, + path[2:], + ) return path @@ -79,10 +92,16 @@ def relpath(path, start=None): when not set the current filename is used. :type start: string """ - if not path.startswith("//"): - if start is None: - start = _os.path.dirname(_bpy.data.filepath) - return "//" + _os.path.relpath(path, start) + if isinstance(path, bytes): + if not path.startswith(b"//"): + if start is None: + start = _os.path.dirname(_getattr_bytes(_bpy.data, "filepath")) + return b"//" + _os.path.relpath(path, start) + else: + if not path.startswith("//"): + if start is None: + start = _os.path.dirname(_bpy.data.filepath) + return "//" + _os.path.relpath(path, start) return path diff --git a/release/scripts/modules/bpy_extras/image_utils.py b/release/scripts/modules/bpy_extras/image_utils.py index 36994d3fddd..5c63ce1218e 100644 --- a/release/scripts/modules/bpy_extras/image_utils.py +++ b/release/scripts/modules/bpy_extras/image_utils.py @@ -31,6 +31,7 @@ def load_image(imagepath, ncase_cmp=True, convert_callback=None, verbose=False, + relpath=None, ): """ Return an image from the file path with options to search multiple paths @@ -57,6 +58,8 @@ def load_image(imagepath, convert it to a PNG and return the PNG's path. For formats blender can read, simply return the path that is given. :type convert_callback: function + :arg relpath: If not None, make the file relative to this path. + :type relpath: None or string :return: an image or None :rtype: :class:`bpy.types.Image` """ @@ -100,6 +103,12 @@ def load_image(imagepath, if place_holder and image is None: image = _image_load_placeholder(path) + if image: + if relpath is not None: + # make relative + from bpy.path import relpath as relpath_fn + image.filepath_raw = relpath_fn(path, start=relpath) + return image # ------------------------------------------------------------------------- diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py index c9063436bb3..8f9fa65cf46 100644 --- a/release/scripts/startup/bl_operators/node.py +++ b/release/scripts/startup/bl_operators/node.py @@ -29,10 +29,14 @@ class NodeAddOperator(): def store_mouse_cursor(context, event): space = context.space_data v2d = context.region.view2d + tree = space.edit_tree # convert mouse position to the View2D for later node placement - space.cursor_location = v2d.region_to_view(event.mouse_region_x, + if context.region.type == 'WINDOW': + space.cursor_location = v2d.region_to_view(event.mouse_region_x, event.mouse_region_y) + else: + space.cursor_location = tree.view_center def create_node(self, context, node_type): space = context.space_data diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 391874ea3dc..b130a8a275d 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -82,6 +82,9 @@ def brush_texture_settings(layout, brush, sculpt): else: layout.row().prop(tex_slot, "tex_paint_map_mode", text="") layout.separator() + + if tex_slot.map_mode == 'STENCIL': + layout.operator("brush.stencil_fit_image_aspect") # angle and texture_angle_source col = layout.column() @@ -117,7 +120,7 @@ def brush_texture_settings(layout, brush, sculpt): def brush_mask_texture_settings(layout, brush): mask_tex_slot = brush.mask_texture_slot - if(brush.mask_texture): + if brush.mask_texture: layout.label(text="Mask Mapping:") col = layout.column() col.active = brush.brush_capabilities.has_texture_angle diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index b02a53302e7..3d7fe59ff77 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -39,7 +39,7 @@ def physics_add(self, layout, md, name, type, typeicon, toggles): if md: sub.context_pointer_set("modifier", md) sub.operator("object.modifier_remove", text=name, text_ctxt=i18n_contexts.default, icon='X') - if(toggles): + if toggles: sub.prop(md, "show_render", text="") sub.prop(md, "show_viewport", text="") else: @@ -59,40 +59,39 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel): bl_options = {'HIDE_HEADER'} def draw(self, context): - ob = context.object + obj = context.object layout = self.layout layout.label("Enable physics for:") split = layout.split() col = split.column() - if(context.object.field.type == 'NONE'): + if obj.field.type == 'NONE': col.operator("object.forcefield_toggle", text="Force Field", icon='FORCE_FORCE') else: col.operator("object.forcefield_toggle", text="Force Field", icon='X') - if(ob.type == 'MESH'): + if obj.type == 'MESH': physics_add(self, col, context.collision, "Collision", 'COLLISION', 'MOD_PHYSICS', False) physics_add(self, col, context.cloth, "Cloth", 'CLOTH', 'MOD_CLOTH', True) physics_add(self, col, context.dynamic_paint, "Dynamic Paint", 'DYNAMIC_PAINT', 'MOD_DYNAMICPAINT', True) col = split.column() - if(ob.type == 'MESH' or ob.type == 'LATTICE'or ob.type == 'CURVE'): + if obj.type in {'MESH', 'LATTICE', 'CURVE'}: physics_add(self, col, context.soft_body, "Soft Body", 'SOFT_BODY', 'MOD_SOFT', True) - if(ob.type == 'MESH'): + if obj.type == 'MESH': physics_add(self, col, context.fluid, "Fluid", 'FLUID_SIMULATION', 'MOD_FLUIDSIM', True) physics_add(self, col, context.smoke, "Smoke", 'SMOKE', 'MOD_SMOKE', True) - if(ob.type == 'MESH'): - physics_add_special(self, col, ob.rigid_body, "Rigid Body", + physics_add_special(self, col, obj.rigid_body, "Rigid Body", "rigidbody.object_add", "rigidbody.object_remove", 'MESH_ICOSPHERE') # XXX: need dedicated icon # all types of objects can have rigid body constraint - physics_add_special(self, col, ob.rigid_body_constraint, "Rigid Body Constraint", + physics_add_special(self, col, obj.rigid_body_constraint, "Rigid Body Constraint", "rigidbody.constraint_add", "rigidbody.constraint_remove", 'CONSTRAINT') # RB_TODO needs better icon diff --git a/release/scripts/startup/bl_ui/space_info.py b/release/scripts/startup/bl_ui/space_info.py index d782bb1b3b9..4ea366e3541 100644 --- a/release/scripts/startup/bl_ui/space_info.py +++ b/release/scripts/startup/bl_ui/space_info.py @@ -304,7 +304,7 @@ class INFO_MT_add(Menu): layout.operator_menu_enum("object.effector_add", "type", text="Force Field", icon='OUTLINER_OB_EMPTY') layout.separator() - if(len(bpy.data.groups) > 10): + if len(bpy.data.groups) > 10: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("object.group_instance_add", text="Group Instance...", icon='OUTLINER_OB_EMPTY') else: @@ -380,7 +380,7 @@ class INFO_MT_help(Menu): layout = self.layout layout.operator("wm.url_open", text="Manual", icon='HELP').url = "http://wiki.blender.org/index.php/Doc:2.6/Manual" - layout.operator("wm.url_open", text="Release Log", icon='URL').url = "http://www.blender.org/development/release-logs/blender-266" + layout.operator("wm.url_open", text="Release Log", icon='URL').url = "http://www.blender.org/development/release-logs/blender-267" layout.separator() layout.operator("wm.url_open", text="Blender Website", icon='URL').url = "http://www.blender.org" diff --git a/release/scripts/startup/bl_ui/space_time.py b/release/scripts/startup/bl_ui/space_time.py index 6af9f377237..becdc792230 100644 --- a/release/scripts/startup/bl_ui/space_time.py +++ b/release/scripts/startup/bl_ui/space_time.py @@ -214,7 +214,7 @@ def marker_menu_generic(layout): layout.operator("marker.add", "Add Marker") layout.operator("marker.duplicate", text="Duplicate Marker") - if(len(bpy.data.scenes) > 10): + if len(bpy.data.scenes) > 10: layout.operator_context = 'INVOKE_DEFAULT' layout.operator("marker.make_links_scene", text="Duplicate Marker to Scene...", icon='OUTLINER_OB_EMPTY') else: diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 8f65eb5b726..39ef38503da 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1113,7 +1113,7 @@ class VIEW3D_MT_make_links(Menu): def draw(self, context): layout = self.layout operator_context_default = layout.operator_context - if(len(bpy.data.scenes) > 10): + if len(bpy.data.scenes) > 10: layout.operator_context = 'INVOKE_REGION_WIN' layout.operator("object.make_links_scene", text="Objects to Scene...", icon='OUTLINER_OB_EMPTY') else: diff --git a/release/text/readme.html b/release/text/readme.html index 54d112c5e2b..f45ec47030a 100644 --- a/release/text/readme.html +++ b/release/text/readme.html @@ -12,18 +12,18 @@ </style> </head> <body> -<p class="title"><b>Blender 2.66</b></p> +<p class="title"><b>Blender 2.67</b></p> <p><br></p> <p class="header"><b>About</b></p> <p class="body">Welcome to Blender, the free, open source 3D application for modeling, animation, rendering, compositing, video editing and game creation. Blender is available for Linux, Mac OS X, Windows and FreeBSD and has a large world-wide community.</p> <p class="body">Blender can be used freely for any purpose, including commercial use and distribution. It's free and open-source software, released under the GNU GPL licence. The entire source code is available on our website.</p> <p class="body">For more information, visit <a href="http://www.blender.org">blender.org</a>.</p> <p><br></p> -<p class="header"><b>2.66</b></p> -<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.66. This release is the seventh official stable release of the Blender 2.6 series, in which we will refine the 2.5 series and add exciting new features. <a href="http://www.blender.org/development/release-logs/blender-266/">More information about this release</a>.</p> +<p class="header"><b>2.67</b></p> +<p class="body">The Blender Foundation and online developer community is proud to present Blender 2.67. This release is the eight official stable release of the Blender 2.6 series, in which we will refine the 2.5 series and add exciting new features. <a href="http://www.blender.org/development/release-logs/blender-267/">More information about this release</a>.</p> <p><br></p> <p class="header"><b>Bugs</b></p> -<p class="body">Although Blender 2.66 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help → Report a Bug from inside Blender. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p> +<p class="body">Although Blender 2.67 is considered a stable release, you may encounter a bug. If you do, please help us by posting it in the bug tracker or using Help → Report a Bug from inside Blender. If it wasn’t reported yet, please log in (or register) and fill in detailed information about the error. Please post detailed instructions on how to reproduce it or post a .blend file showcasing the bug.</p> <p><br></p> <p class="header"><b>Package Contents</b></p> <p class="body">The downloaded Blender package includes:</p> @@ -47,7 +47,7 @@ <p class="header"><b>Links</b></p> <p class="body">Users:</p> <p class="body"> General information <a href="http://www.blender.org">www.blender.org</a> <br> - Full release log <a href="http://www.blender.org/development/release-logs/blender-266/">www.blender.org/development/release-logs/blender-266/</a><br> + Full release log <a href="http://www.blender.org/development/release-logs/blender-267/">www.blender.org/development/release-logs/blender-267/</a><br> Tutorials <a href="http://www.blender.org/education-help/">www.blender.org/education-help/</a> <br> Manual <a href="http://wiki.blender.org/index.php/Doc:2.6/Manual">wiki.blender.org/index.php/Doc:2.6/Manual</a><br> User Forum <a href="http://www.blenderartists.org">www.blenderartists.org</a><br> diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index 6e298a6d4f6..8ae7155c205 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -87,7 +87,7 @@ float *BKE_curve_make_orco(struct Scene *scene, struct Object *ob); float *BKE_curve_surf_make_orco(struct Object *ob); void BKE_curve_bevelList_make(struct Object *ob); -void BKE_curve_bevel_make(struct Scene *scene, struct Object *ob, struct ListBase *disp, int forRender); +void BKE_curve_bevel_make(struct Scene *scene, struct Object *ob, struct ListBase *disp, int forRender, int renderResolution); void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride); diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 10c31189d02..b5d018cd4eb 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -87,9 +87,9 @@ void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface, int *to void BKE_displist_free(struct ListBase *lb); bool BKE_displist_has_faces(struct ListBase *lb); -void BKE_displist_make_surf(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **derivedFinal, int forRender, int forOrco); +void BKE_displist_make_surf(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **derivedFinal, int forRender, int forOrco, int renderResolution); void BKE_displist_make_curveTypes(struct Scene *scene, struct Object *ob, int forOrco); -void BKE_displist_make_curveTypes_forRender(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **derivedFinal, int forOrco); +void BKE_displist_make_curveTypes_forRender(struct Scene *scene, struct Object *ob, struct ListBase *dispbase, struct DerivedMesh **derivedFinal, int forOrco, int renderResolution); void BKE_displist_make_curveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase); void BKE_displist_make_mball(struct Scene *scene, struct Object *ob); void BKE_displist_make_mball_forRender(struct Scene *scene, struct Object *ob, struct ListBase *dispbase); @@ -100,6 +100,6 @@ void BKE_displist_fill(struct ListBase *dispbase, struct ListBase *to, int flipn float BKE_displist_calc_taper(struct Scene *scene, struct Object *taperobj, int cur, int tot); /* add Orco layer to the displist object which has got derived mesh and return orco */ -float *BKE_displist_make_orco(struct Scene *scene, struct Object *ob, struct DerivedMesh *derivedFinal, int forRender); +float *BKE_displist_make_orco(struct Scene *scene, struct Object *ob, struct DerivedMesh *derivedFinal, int forRender, int renderResolution); #endif diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 56f2237a61f..10c18fe94ad 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -1418,7 +1418,7 @@ float *BKE_curve_make_orco(Scene *scene, Object *ob) /* ***************** BEVEL ****************** */ -void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRender) +void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRender, int renderResolution) { DispList *dl, *dlnew; Curve *bevcu, *cu; @@ -1442,7 +1442,7 @@ void BKE_curve_bevel_make(Scene *scene, Object *ob, ListBase *disp, int forRende facy = cu->bevobj->size[1]; if (forRender) { - BKE_displist_make_curveTypes_forRender(scene, cu->bevobj, &bevdisp, NULL, 0); + BKE_displist_make_curveTypes_forRender(scene, cu->bevobj, &bevdisp, NULL, 0, renderResolution); dl = bevdisp.first; } else { diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 9a012f9c009..b6df16db6aa 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -302,7 +302,7 @@ bool BKE_displist_surfindex_get(DispList *dl, int a, int *b, int *p1, int *p2, i /* ****************** make displists ********************* */ -static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, int forRender) +static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, int forRender, int renderResolution) { Nurb *nu; DispList *dl; @@ -315,7 +315,7 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i nu = nubase->first; while (nu) { if (nu->hide == 0 || editmode == 0) { - if (forRender && cu->resolu_ren != 0) + if (renderResolution && cu->resolu_ren != 0) resolu = cu->resolu_ren; else resolu = nu->resolu; @@ -731,13 +731,13 @@ void BKE_displist_make_mball_forRender(Scene *scene, Object *ob, ListBase *dispb object_deform_mball(ob, dispbase); } -static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob, int forRender, int editmode) +static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob, int renderResolution, int editmode) { ModifierData *md = modifiers_getVirtualModifierList(ob); ModifierData *pretessellatePoint; int required_mode; - if (forRender) + if (renderResolution) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; @@ -771,7 +771,8 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob, int fo return pretessellatePoint; } -static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, float (**originalVerts_r)[3], +static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, int renderResolution, + float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r) { ModifierData *md = modifiers_getVirtualModifierList(ob); @@ -788,14 +789,14 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl if (editmode) app_flag |= MOD_APPLY_USECACHE; - if (forRender) { + if (renderResolution) { app_flag |= MOD_APPLY_RENDER; required_mode = eModifierMode_Render; } else required_mode = eModifierMode_Realtime; - pretessellatePoint = curve_get_tessellate_point(scene, ob, forRender, editmode); + pretessellatePoint = curve_get_tessellate_point(scene, ob, renderResolution, editmode); if (editmode) required_mode |= eModifierMode_Editmode; @@ -885,7 +886,8 @@ static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3]) } static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase, DerivedMesh **derivedFinal, - int forRender, float (*originalVerts)[3], float (*deformedVerts)[3]) + int forRender, int renderResolution, + float (*originalVerts)[3], float (*deformedVerts)[3]) { ModifierData *md = modifiers_getVirtualModifierList(ob); ModifierData *pretessellatePoint; @@ -898,14 +900,14 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba int useCache = !forRender; ModifierApplyFlag app_flag = 0; - if (forRender) { + if (renderResolution) { app_flag |= MOD_APPLY_RENDER; required_mode = eModifierMode_Render; } else required_mode = eModifierMode_Realtime; - pretessellatePoint = curve_get_tessellate_point(scene, ob, forRender, editmode); + pretessellatePoint = curve_get_tessellate_point(scene, ob, renderResolution, editmode); if (editmode) required_mode |= eModifierMode_Editmode; @@ -1109,7 +1111,7 @@ static void add_orco_dm(Scene *scene, Object *ob, DerivedMesh *dm, DerivedMesh * DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco); } -static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) +static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender, int renderResolution) { /* this function represents logic of mesh's orcodm calculation * for displist-based objects @@ -1121,14 +1123,14 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina int required_mode; int editmode = (!forRender && (cu->editnurb || cu->editfont)); DerivedMesh *ndm, *orcodm = NULL; - const ModifierApplyFlag app_flag = forRender ? MOD_APPLY_RENDER : 0; + const ModifierApplyFlag app_flag = renderResolution ? MOD_APPLY_RENDER : 0; - if (forRender) + if (renderResolution) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; - pretessellatePoint = curve_get_tessellate_point(scene, ob, forRender, editmode); + pretessellatePoint = curve_get_tessellate_point(scene, ob, renderResolution, editmode); if (editmode) required_mode |= eModifierMode_Editmode; @@ -1169,7 +1171,7 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina } void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase, - DerivedMesh **derivedFinal, int forRender, int forOrco) + DerivedMesh **derivedFinal, int forRender, int forOrco, int renderResolution) { ListBase *nubase; Nurb *nu; @@ -1187,13 +1189,13 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase, nubase = &cu->nurb; if (!forOrco) - curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts); + curve_calc_modifiers_pre(scene, ob, forRender, renderResolution, &originalVerts, &deformedVerts, &numVerts); for (nu = nubase->first; nu; nu = nu->next) { if (forRender || nu->hide == 0) { int resolu = nu->resolu, resolv = nu->resolv; - if (forRender) { + if (renderResolution) { if (cu->resolu_ren) resolu = cu->resolu_ren; if (cu->resolv_ren) @@ -1263,7 +1265,8 @@ void BKE_displist_make_surf(Scene *scene, Object *ob, ListBase *dispbase, if (!forOrco) { curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, - forRender, originalVerts, deformedVerts); + forRender, renderResolution, + originalVerts, deformedVerts); } } @@ -1350,7 +1353,7 @@ static void fillBevelCap(Nurb *nu, DispList *dlb, float *prev_fp, ListBase *disp } static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispbase, - DerivedMesh **derivedFinal, int forRender, int forOrco) + DerivedMesh **derivedFinal, int forRender, int forOrco, int renderResolution) { Curve *cu = ob->data; @@ -1358,7 +1361,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba if (!ELEM3(ob->type, OB_SURF, OB_CURVE, OB_FONT)) return; if (ob->type == OB_SURF) { - BKE_displist_make_surf(scene, ob, dispbase, derivedFinal, forRender, forOrco); + BKE_displist_make_surf(scene, ob, dispbase, derivedFinal, forRender, forOrco, renderResolution); } else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { ListBase dlbev; @@ -1378,16 +1381,16 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba BKE_vfont_to_curve(G.main, scene, ob, 0); if (!forOrco) - curve_calc_modifiers_pre(scene, ob, forRender, &originalVerts, &deformedVerts, &numVerts); + curve_calc_modifiers_pre(scene, ob, forRender, renderResolution, &originalVerts, &deformedVerts, &numVerts); BKE_curve_bevelList_make(ob); /* If curve has no bevel will return nothing */ - BKE_curve_bevel_make(scene, ob, &dlbev, forRender); + BKE_curve_bevel_make(scene, ob, &dlbev, forRender, renderResolution); /* no bevel or extrude, and no width correction? */ if (!dlbev.first && cu->width == 1.0f) { - curve_to_displist(cu, nubase, dispbase, forRender); + curve_to_displist(cu, nubase, dispbase, forRender, renderResolution); } else { float widfac = cu->width - 1.0f; @@ -1569,7 +1572,7 @@ static void do_makeDispListCurveTypes(Scene *scene, Object *ob, ListBase *dispba } if (!forOrco) - curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, originalVerts, deformedVerts); + curve_calc_modifiers_post(scene, ob, dispbase, derivedFinal, forRender, renderResolution, originalVerts, deformedVerts); if (cu->flag & CU_DEFORM_FILL && !ob->derivedFinal) { curve_to_filledpoly(cu, nubase, dispbase); @@ -1595,7 +1598,7 @@ void BKE_displist_make_curveTypes(Scene *scene, Object *ob, int forOrco) /* free displist used for textspace */ BKE_displist_free(&cu->disp); - do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco); + do_makeDispListCurveTypes(scene, ob, dispbase, &ob->derivedFinal, 0, forOrco, 0); if (ob->derivedFinal) { DM_set_object_boundbox(ob, ob->derivedFinal); @@ -1612,18 +1615,18 @@ void BKE_displist_make_curveTypes(Scene *scene, Object *ob, int forOrco) } void BKE_displist_make_curveTypes_forRender(Scene *scene, Object *ob, ListBase *dispbase, - DerivedMesh **derivedFinal, int forOrco) + DerivedMesh **derivedFinal, int forOrco, int renderResolution) { - do_makeDispListCurveTypes(scene, ob, dispbase, derivedFinal, 1, forOrco); + do_makeDispListCurveTypes(scene, ob, dispbase, derivedFinal, 1, forOrco, renderResolution); } void BKE_displist_make_curveTypes_forOrco(struct Scene *scene, struct Object *ob, struct ListBase *dispbase) { - do_makeDispListCurveTypes(scene, ob, dispbase, NULL, 1, 1); + do_makeDispListCurveTypes(scene, ob, dispbase, NULL, 1, 1, 1); } /* add Orco layer to the displist object which has got derived mesh and return orco */ -float *BKE_displist_make_orco(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) +float *BKE_displist_make_orco(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender, int renderResolution) { float *orco; @@ -1631,7 +1634,7 @@ float *BKE_displist_make_orco(Scene *scene, Object *ob, DerivedMesh *derivedFina derivedFinal = ob->derivedFinal; if (!derivedFinal->getVertDataArray(derivedFinal, CD_ORCO)) { - curve_calc_orcodm(scene, ob, derivedFinal, forRender); + curve_calc_orcodm(scene, ob, derivedFinal, forRender, renderResolution); } orco = derivedFinal->getVertDataArray(derivedFinal, CD_ORCO); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 0863517c7d7..6b8f0348e16 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -1585,7 +1585,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value float fuel_flow = emission_value * sfs->fuel_amount; /* add heat */ if (heat) { - heat[index] = MAX2(emission_value * sfs->temp, heat[index]); + heat[index] = ADD_IF_LOWER(heat[index], emission_value * sfs->temp); } /* absolute */ if (absolute_flow) { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 011f9df6f8c..f01b2bcc5a7 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -727,6 +727,9 @@ static void write_node_socket_interface(WriteData *wd, bNodeTree *UNUSED(ntree), if (sock->prop) IDP_WriteProperty(sock->prop, wd); + + if (sock->default_value) + writedata(wd, DATA, MEM_allocN_len(sock->default_value), sock->default_value); } /* this is only direct data, tree itself should have been written */ static void write_nodetree(WriteData *wd, bNodeTree *ntree) diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index 44392383925..c0db2c0a19e 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -776,6 +776,27 @@ bool BM_edge_is_contiguous(BMEdge *e) } /** + * Check if the edge is convex or concave + * (depends on face winding) + */ +bool BM_edge_is_convex(BMEdge *e) +{ + if (BM_edge_is_manifold(e)) { + BMLoop *l1 = e->l; + BMLoop *l2 = e->l->radial_next; + if (!equals_v3v3(l1->f->no, l2->f->no)) { + float cross[3]; + float l_dir[3]; + cross_v3_v3v3(cross, l1->f->no, l2->f->no); + /* we assume contiguous normals, otherwise the result isn't meaningful */ + sub_v3_v3v3(l_dir, l1->next->v->co, l1->v->co); + return (dot_v3v3(l_dir, cross) > 0.0f); + } + } + return true; +} + +/** * Tests whether or not an edge is on the boundary * of a shell (has one face associated with it) */ @@ -1153,6 +1174,27 @@ float BM_edge_calc_face_angle(BMEdge *e) } /** + * \brief BMESH EDGE/FACE ANGLE + * + * Calculates the angle between two faces. + * Assumes the face normals are correct. + * + * \return angle in radians + */ +float BM_edge_calc_face_angle_signed(BMEdge *e) +{ + if (BM_edge_is_manifold(e)) { + BMLoop *l1 = e->l; + BMLoop *l2 = e->l->radial_next; + const float angle = angle_normalized_v3v3(l1->f->no, l2->f->no); + return BM_edge_is_convex(e) ? angle : -angle; + } + else { + return DEG2RADF(90.0f); + } +} + +/** * \brief BMESH EDGE/FACE TANGENT * * Calculate the tangent at this loop corner or fallback to the face normal on straight lines. diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 8326709a2eb..ec52a7af162 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -62,6 +62,7 @@ bool BM_vert_is_manifold(BMVert *v); bool BM_edge_is_manifold(BMEdge *e); bool BM_edge_is_boundary(BMEdge *e); bool BM_edge_is_contiguous(BMEdge *e); +bool BM_edge_is_convex(BMEdge *e); bool BM_loop_is_convex(BMLoop *l); @@ -71,6 +72,7 @@ void BM_loop_calc_face_direction(BMLoop *l, float r_normal[3]); void BM_loop_calc_face_tangent(BMLoop *l, float r_tangent[3]); float BM_edge_calc_face_angle(BMEdge *e); +float BM_edge_calc_face_angle_signed(BMEdge *e); void BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3]); float BM_vert_calc_edge_angle(BMVert *v); diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp b/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp index d85b1ec1de1..aeed859b350 100644 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp +++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.cpp @@ -66,7 +66,7 @@ void ColorBalanceNode::convertToOperations(ExecutionSystem *graph, CompositorCon } inputSocket->relinkConnections(operation->getInputSocket(0), 0, graph); - inputImageSocket->relinkConnections(operation->getInputSocket(1), 0, graph); + inputImageSocket->relinkConnections(operation->getInputSocket(1), 1, graph); outputSocket->relinkConnections(operation->getOutputSocket(0)); graph->addOperation(operation); } diff --git a/source/blender/compositor/nodes/COM_ZCombineNode.cpp b/source/blender/compositor/nodes/COM_ZCombineNode.cpp index f48fca72c05..35eedf435f6 100644 --- a/source/blender/compositor/nodes/COM_ZCombineNode.cpp +++ b/source/blender/compositor/nodes/COM_ZCombineNode.cpp @@ -27,39 +27,72 @@ #include "COM_ExecutionSystem.h" #include "COM_SetValueOperation.h" #include "COM_MathBaseOperation.h" +#include "COM_AntiAliasOperation.h" +#include "COM_MixBlendOperation.h" #include "DNA_material_types.h" // the ramp types void ZCombineNode::convertToOperations(ExecutionSystem *system, CompositorContext *context) { - if (this->getOutputSocket(0)->isConnected()) { - ZCombineOperation *operation = NULL; - if (this->getbNode()->custom1) { - operation = new ZCombineAlphaOperation(); + if (context->getRenderData()->scemode & R_FULL_SAMPLE) { + if (this->getOutputSocket(0)->isConnected()) { + ZCombineOperation *operation = NULL; + if (this->getbNode()->custom1) { + operation = new ZCombineAlphaOperation(); + } + else { + operation = new ZCombineOperation(); + } + + this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system); + this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, system); + this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, system); + this->getInputSocket(3)->relinkConnections(operation->getInputSocket(3), 3, system); + this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); + system->addOperation(operation); + if (this->getOutputSocket(1)->isConnected()) { + MathMinimumOperation *zoperation = new MathMinimumOperation(); + addLink(system, operation->getInputSocket(1)->getConnection()->getFromSocket(), zoperation->getInputSocket(0)); + addLink(system, operation->getInputSocket(3)->getConnection()->getFromSocket(), zoperation->getInputSocket(1)); + this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket()); + system->addOperation(zoperation); + } } else { - operation = new ZCombineOperation(); + if (this->getOutputSocket(1)->isConnected()) { + MathMinimumOperation *zoperation = new MathMinimumOperation(); + this->getInputSocket(1)->relinkConnections(zoperation->getInputSocket(0), 1, system); + this->getInputSocket(3)->relinkConnections(zoperation->getInputSocket(1), 3, system); + this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket()); + system->addOperation(zoperation); + } } + } else { + // not full anti alias, use masking for Z combine. be aware it uses anti aliasing. + // step 1 create mask + MathGreaterThanOperation *maskoperation = new MathGreaterThanOperation(); + this->getInputSocket(1)->relinkConnections(maskoperation->getInputSocket(0), 1, system); + this->getInputSocket(3)->relinkConnections(maskoperation->getInputSocket(1), 3, system); + + // step 2 anti alias mask bit of an expensive operation, but does the trick + AntiAliasOperation *antialiasoperation = new AntiAliasOperation(); + addLink(system, maskoperation->getOutputSocket(), antialiasoperation->getInputSocket(0)); + + // use mask to blend between the input colors. + ZCombineMaskOperation *zcombineoperation = this->getbNode()->custom1?new ZCombineMaskAlphaOperation():new ZCombineMaskOperation(); + addLink(system, antialiasoperation->getOutputSocket(), zcombineoperation->getInputSocket(0)); + this->getInputSocket(0)->relinkConnections(zcombineoperation->getInputSocket(1), 0, system); + this->getInputSocket(2)->relinkConnections(zcombineoperation->getInputSocket(2), 2, system); + this->getOutputSocket(0)->relinkConnections(zcombineoperation->getOutputSocket()); + + system->addOperation(maskoperation); + system->addOperation(antialiasoperation); + system->addOperation(zcombineoperation); - this->getInputSocket(0)->relinkConnections(operation->getInputSocket(0), 0, system); - this->getInputSocket(1)->relinkConnections(operation->getInputSocket(1), 1, system); - this->getInputSocket(2)->relinkConnections(operation->getInputSocket(2), 2, system); - this->getInputSocket(3)->relinkConnections(operation->getInputSocket(3), 3, system); - this->getOutputSocket(0)->relinkConnections(operation->getOutputSocket()); - system->addOperation(operation); - if (this->getOutputSocket(1)->isConnected()) { - MathMinimumOperation *zoperation = new MathMinimumOperation(); - addLink(system, operation->getInputSocket(1)->getConnection()->getFromSocket(), zoperation->getInputSocket(0)); - addLink(system, operation->getInputSocket(3)->getConnection()->getFromSocket(), zoperation->getInputSocket(1)); - this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket()); - system->addOperation(zoperation); - } - } - else { if (this->getOutputSocket(1)->isConnected()) { MathMinimumOperation *zoperation = new MathMinimumOperation(); - this->getInputSocket(1)->relinkConnections(zoperation->getInputSocket(0), 1, system); - this->getInputSocket(3)->relinkConnections(zoperation->getInputSocket(1), 3, system); + addLink(system, maskoperation->getInputSocket(0)->getConnection()->getFromSocket(), zoperation->getInputSocket(0)); + addLink(system, maskoperation->getInputSocket(1)->getConnection()->getFromSocket(), zoperation->getInputSocket(1)); this->getOutputSocket(1)->relinkConnections(zoperation->getOutputSocket()); system->addOperation(zoperation); } diff --git a/source/blender/compositor/operations/COM_MixHueOperation.cpp b/source/blender/compositor/operations/COM_MixHueOperation.cpp index 5688d6b26f0..1fa393bb362 100644 --- a/source/blender/compositor/operations/COM_MixHueOperation.cpp +++ b/source/blender/compositor/operations/COM_MixHueOperation.cpp @@ -56,6 +56,8 @@ void MixHueOperation::executePixel(float output[4], float x, float y, PixelSampl output[0] = valuem * (inputColor1[0]) + value * tmpr; output[1] = valuem * (inputColor1[1]) + value * tmpg; output[2] = valuem * (inputColor1[2]) + value * tmpb; + } else { + copy_v3_v3(output, inputColor1); } output[3] = inputColor1[3]; diff --git a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp index 401ad8d4247..69207d7fbaa 100644 --- a/source/blender/compositor/operations/COM_MixSaturationOperation.cpp +++ b/source/blender/compositor/operations/COM_MixSaturationOperation.cpp @@ -52,7 +52,10 @@ void MixSaturationOperation::executePixel(float output[4], float x, float y, Pix float colH, colS, colV; rgb_to_hsv(inputColor2[0], inputColor2[1], inputColor2[2], &colH, &colS, &colV); hsv_to_rgb(rH, (valuem * rS + value * colS), rV, &output[0], &output[1], &output[2]); + } else { + copy_v3_v3(output, inputColor1); } + output[3] = inputColor1[3]; clampIfNeeded(output); diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.cpp b/source/blender/compositor/operations/COM_ZCombineOperation.cpp index 5e4f90b0269..97a4aefbfac 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.cpp +++ b/source/blender/compositor/operations/COM_ZCombineOperation.cpp @@ -92,3 +92,71 @@ void ZCombineOperation::deinitExecution() this->m_image2Reader = NULL; this->m_depth2Reader = NULL; } + +// MASK combine +ZCombineMaskOperation::ZCombineMaskOperation() : NodeOperation() +{ + this->addInputSocket(COM_DT_VALUE); //mask + this->addInputSocket(COM_DT_COLOR); + this->addInputSocket(COM_DT_COLOR); + this->addOutputSocket(COM_DT_COLOR); + + this->m_maskReader = NULL; + this->m_image1Reader = NULL; + this->m_image2Reader = NULL; +} + +void ZCombineMaskOperation::initExecution() +{ + this->m_maskReader = this->getInputSocketReader(0); + this->m_image1Reader = this->getInputSocketReader(1); + this->m_image2Reader = this->getInputSocketReader(2); +} + +void ZCombineMaskOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +{ + float mask[4]; + float color1[4]; + float color2[4]; + + this->m_maskReader->read(mask, x, y, sampler); + this->m_image1Reader->read(color1, x, y, sampler); + this->m_image2Reader->read(color2, x, y, sampler); + + float fac = mask[0]; + // multiply mask with alpha, if mask == 0 color1, else color2 make sure + float mfac = 1.0f-fac; + output[0] = color1[0]*mfac + color2[0]*fac; + output[1] = color1[1]*mfac + color2[1]*fac; + output[2] = color1[2]*mfac + color2[2]*fac; + output[3] = max(color1[3], color2[3]); +} + +void ZCombineMaskAlphaOperation::executePixel(float output[4], float x, float y, PixelSampler sampler) +{ + float mask[4]; + float color1[4]; + float color2[4]; + + this->m_maskReader->read(mask, x, y, sampler); + this->m_image1Reader->read(color1, x, y, sampler); + this->m_image2Reader->read(color2, x, y, sampler); + + float fac = mask[0]; + // multiply mask with alpha, if mask == 0 color1, else color2 make sure + float mfac = 1.0f-fac; + float alpha = color1[3]*mfac + color2[3]*fac; + float facalpha = fac * alpha; + mfac = 1.0f-facalpha; + output[0] = color1[0]*mfac + color2[0]*facalpha; + output[1] = color1[1]*mfac + color2[1]*facalpha; + output[2] = color1[2]*mfac + color2[2]*facalpha; + output[3] = max(color1[3], color2[3]); +} + +void ZCombineMaskOperation::deinitExecution() +{ + this->m_image1Reader = NULL; + this->m_maskReader = NULL; + this->m_image2Reader = NULL; +} diff --git a/source/blender/compositor/operations/COM_ZCombineOperation.h b/source/blender/compositor/operations/COM_ZCombineOperation.h index 61ceca340f7..4545775f26f 100644 --- a/source/blender/compositor/operations/COM_ZCombineOperation.h +++ b/source/blender/compositor/operations/COM_ZCombineOperation.h @@ -54,4 +54,20 @@ class ZCombineAlphaOperation : public ZCombineOperation { void executePixel(float output[4], float x, float y, PixelSampler sampler); }; +class ZCombineMaskOperation : public NodeOperation { +protected: + SocketReader *m_maskReader; + SocketReader *m_image1Reader; + SocketReader *m_image2Reader; +public: + ZCombineMaskOperation(); + + void initExecution(); + void deinitExecution(); + void executePixel(float output[4], float x, float y, PixelSampler sampler); +}; +class ZCombineMaskAlphaOperation : public ZCombineMaskOperation { + void executePixel(float output[4], float x, float y, PixelSampler sampler); +}; + #endif diff --git a/source/blender/editors/include/BIF_glutil.h b/source/blender/editors/include/BIF_glutil.h index af2dc884508..dfb02fa9c1b 100644 --- a/source/blender/editors/include/BIF_glutil.h +++ b/source/blender/editors/include/BIF_glutil.h @@ -35,6 +35,8 @@ struct rctf; struct ImBuf; struct bContext; +struct ColorManagedViewSettings; +struct ColorManagedDisplaySettings; void fdrawbezier(float vec[4][3]); void fdrawline(float x1, float y1, float x2, float y2); @@ -213,6 +215,11 @@ void bgl_get_mats(bglMats *mats); /* **** Color management helper functions for GLSL display/transform ***** */ /* Draw imbuf on a screen, preferably using GLSL display transform */ +void glaDrawImBuf_glsl(struct ImBuf *ibuf, float x, float y, int zoomfilter, + struct ColorManagedViewSettings *view_settings, + struct ColorManagedDisplaySettings *display_settings); + +/* Draw imbuf on a screen, preferably using GLSL display transform */ void glaDrawImBuf_glsl_ctx(const struct bContext *C, struct ImBuf *ibuf, float x, float y, int zoomfilter); /* Transform buffer from role to scene linear space using GLSL OCIO conversion */ diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index a39476dad66..36ce7606a13 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -114,19 +114,19 @@ void EDBM_select_flush(struct BMEditMesh *em); void undo_push_mesh(struct bContext *C, const char *name); -int EDBM_vert_color_check(struct BMEditMesh *em); +bool EDBM_vert_color_check(struct BMEditMesh *em); -void EDBM_mesh_hide(struct BMEditMesh *em, int swap); +void EDBM_mesh_hide(struct BMEditMesh *em, bool swap); void EDBM_mesh_reveal(struct BMEditMesh *em); void EDBM_update_generic(struct BMEditMesh *em, const bool do_tessface, const bool is_destructive); -struct UvElementMap *EDBM_uv_element_map_create(struct BMEditMesh *em, int selected, int doIslands); +struct UvElementMap *EDBM_uv_element_map_create(struct BMEditMesh *em, const bool selected, const bool do_islands); void EDBM_uv_element_map_free(struct UvElementMap *vmap); struct UvElement *ED_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l); -int EDBM_mtexpoly_check(struct BMEditMesh *em); -struct MTexPoly *EDBM_mtexpoly_active_get(struct BMEditMesh *em, struct BMFace **r_act_efa, int sloppy, int selected); +bool EDBM_mtexpoly_check(struct BMEditMesh *em); +struct MTexPoly *EDBM_mtexpoly_active_get(struct BMEditMesh *em, struct BMFace **r_act_efa, const bool sloppy, const bool selected); void EDBM_uv_vert_map_free(struct UvVertMap *vmap); struct UvMapVert *EDBM_uv_vert_map_at_index(struct UvVertMap *vmap, unsigned int v); @@ -138,7 +138,7 @@ void EDBM_flag_disable_all(struct BMEditMesh *em, const char hflag); /* editmesh_select.c */ void EDBM_select_mirrored(struct Object *obedit, struct BMEditMesh *em, bool extend); -void EDBM_automerge(struct Scene *scene, struct Object *ob, int update); +void EDBM_automerge(struct Scene *scene, struct Object *ob, bool update); bool EDBM_backbuf_border_init(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); int EDBM_backbuf_check(unsigned int index); @@ -170,7 +170,7 @@ void EDBM_deselect_by_material(struct BMEditMesh *em, const short index, const s void EDBM_select_toggle_all(struct BMEditMesh *em); void EDBM_select_swap(struct BMEditMesh *em); /* exported for UV */ -int EDBM_select_interior_faces(struct BMEditMesh *em); +bool EDBM_select_interior_faces(struct BMEditMesh *em); void em_setup_viewcontext(struct bContext *C, struct ViewContext *vc); /* rename? */ extern unsigned int bm_vertoffs, bm_solidoffs, bm_wireoffs; @@ -192,7 +192,7 @@ void paintface_deselect_all_visible(struct Object *ob, int action, bool flush_fl void paintface_select_linked(struct bContext *C, struct Object *ob, const int mval[2], int mode); bool paintface_minmax(struct Object *ob, float r_min[3], float r_max[3]); -void paintface_hide(struct Object *ob, const int unselected); +void paintface_hide(struct Object *ob, const bool unselected); void paintface_reveal(struct Object *ob); void paintvert_deselect_all_visible(struct Object *ob, int action, bool flush_flags); @@ -223,13 +223,14 @@ struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, const char *name); void ED_vgroup_delete(struct Object *ob, struct bDeformGroup *defgroup); void ED_vgroup_clear(struct Object *ob); void ED_vgroup_select_by_name(struct Object *ob, const char *name); -int ED_vgroup_data_create(struct ID *id); +bool ED_vgroup_data_create(struct ID *id); void ED_vgroup_data_clamp_range(struct ID *id, const int total); -int ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot); -int ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from); -void ED_vgroup_mirror(struct Object *ob, const short mirror_weights, const short flip_vgroups, const short all_vgroups); +bool ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot); +bool ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from); +void ED_vgroup_mirror(struct Object *ob, + const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups); -int ED_vgroup_object_is_edit_mode(struct Object *ob); +bool ED_vgroup_object_is_edit_mode(struct Object *ob); void ED_vgroup_vert_add(struct Object *ob, struct bDeformGroup *dg, int vertnum, float weight, int assignmode); void ED_vgroup_vert_remove(struct Object *ob, struct bDeformGroup *dg, int vertnum); @@ -253,13 +254,13 @@ void ED_mesh_calc_normals(struct Mesh *me); void ED_mesh_calc_tessface(struct Mesh *mesh); void ED_mesh_update(struct Mesh *mesh, struct bContext *C, int calc_edges, int calc_tessface); -int ED_mesh_uv_texture_add(struct Mesh *me, const char *name, const bool active_set); +int ED_mesh_uv_texture_add(struct Mesh *me, const char *name, const bool active_set); bool ED_mesh_uv_texture_remove_index(struct Mesh *me, const int n); bool ED_mesh_uv_texture_remove_active(struct Mesh *me); bool ED_mesh_uv_texture_remove_named(struct Mesh *me, const char *name); -int ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me); -int ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum); -int ED_mesh_color_add(struct Mesh *me, const char *name, const bool active_set); +void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me); +void ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum); +int ED_mesh_color_add(struct Mesh *me, const char *name, const bool active_set); bool ED_mesh_color_remove_index(struct Mesh *me, const int n); bool ED_mesh_color_remove_active(struct Mesh *me); bool ED_mesh_color_remove_named(struct Mesh *me, const char *name); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index ee0946be620..091bc583360 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -243,7 +243,7 @@ void view3d_validate_backbuf(struct ViewContext *vc); struct ImBuf *view3d_read_backbuf(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); unsigned int view3d_sample_backbuf_rect(struct ViewContext *vc, const int mval[2], int size, unsigned int min, unsigned int max, float *dist, short strict, - void *handle, unsigned int (*indextest)(void *handle, unsigned int index)); + void *handle, bool (*indextest)(void *handle, unsigned int index)); unsigned int view3d_sample_backbuf(struct ViewContext *vc, int x, int y); /* draws and does a 4x4 sample */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 0c484a82778..480c4a83507 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -819,7 +819,7 @@ static void ui_menu_block_set_keyaccels(uiBlock *block) /* XXX, this code will shorten any allocated string to 'UI_MAX_NAME_STR' * since this is really long its unlikely to be an issue, * but this could be supported */ -void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const short do_strip) +void ui_but_add_shortcut(uiBut *but, const char *shortcut_str, const bool do_strip) { if (do_strip) { diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index a644feca080..c40d91378b1 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -124,14 +124,14 @@ typedef struct uiHandleButtonData { wmWindow *window; ARegion *region; - int interactive; + bool interactive; /* overall state */ uiHandleButtonState state; int retval; /* booleans (could be made into flags) */ - char cancel, escapecancel; - char applied, appliedinteractive; + bool cancel, escapecancel; + bool applied, applied_interactive; wmTimer *flashtimer; /* edited value */ @@ -146,7 +146,7 @@ typedef struct uiHandleButtonData { wmTimer *tooltiptimer; /* auto open */ - int used_mouse; + bool used_mouse; wmTimer *autoopentimer; /* text selection/editing */ @@ -156,7 +156,8 @@ typedef struct uiHandleButtonData { /* coords are Window/uiBlock relative (depends on the button) */ int draglastx, draglasty; int dragstartx, dragstarty; - int dragchange, draglock, dragsel; + bool dragchange, draglock; + int dragsel; float dragf, dragfstart; CBData *dragcbd; @@ -257,7 +258,7 @@ void ui_pan_to_scroll(const wmEvent *event, int *type, int *val) } } -static int ui_but_editable(uiBut *but) +static bool ui_but_editable(uiBut *but) { return ELEM5(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR); } @@ -517,7 +518,7 @@ static void ui_apply_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data) ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_BUTM(bContext *C, uiBut *but, uiHandleButtonData *data) @@ -526,7 +527,7 @@ static void ui_apply_but_BUTM(bContext *C, uiBut *but, uiHandleButtonData *data) ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data) @@ -537,7 +538,7 @@ static void ui_apply_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data ui_check_but(but); ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data) @@ -600,7 +601,7 @@ static void ui_apply_but_TOG(bContext *C, uiBut *but, uiHandleButtonData *data) ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data) @@ -617,7 +618,7 @@ static void ui_apply_but_ROW(bContext *C, uiBlock *block, uiBut *but, uiHandleBu ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data) @@ -636,7 +637,7 @@ static void ui_apply_but_TEX(bContext *C, uiBut *but, uiHandleButtonData *data) ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) @@ -646,7 +647,7 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) data->value = ui_get_but_val(but); } else { - data->cancel = TRUE; + data->cancel = true; return; } } @@ -657,7 +658,7 @@ static void ui_apply_but_NUM(bContext *C, uiBut *but, uiHandleButtonData *data) ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_TOG3(bContext *C, uiBut *but, uiHandleButtonData *data) @@ -692,7 +693,7 @@ static void ui_apply_but_TOG3(bContext *C, uiBut *but, uiHandleButtonData *data) ui_check_but(but); ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_VEC(bContext *C, uiBut *but, uiHandleButtonData *data) @@ -702,21 +703,21 @@ static void ui_apply_but_VEC(bContext *C, uiBut *but, uiHandleButtonData *data) ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_COLORBAND(bContext *C, uiBut *but, uiHandleButtonData *data) { ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_CURVE(bContext *C, uiBut *but, uiHandleButtonData *data) { ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_IDPOIN(bContext *C, uiBut *but, uiHandleButtonData *data) @@ -725,7 +726,7 @@ static void ui_apply_but_IDPOIN(bContext *C, uiBut *but, uiHandleButtonData *dat ui_check_but(but); ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } #ifdef WITH_INTERNATIONAL @@ -733,7 +734,7 @@ static void ui_apply_but_CHARTAB(bContext *C, uiBut *but, uiHandleButtonData *da { ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } #endif @@ -884,7 +885,7 @@ static int ui_handler_region_drag_toggle(bContext *C, const wmEvent *event, void #endif /* USE_DRAG_TOGGLE */ -static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *event) +static bool ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *event) { rcti rect; int x = event->x, y = event->y; @@ -908,7 +909,7 @@ static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, const wmEvent *even return BLI_rcti_isect_pt(&rect, x, y); } -static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event) +static bool ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { /* prevent other WM gestures to start while we try to drag */ WM_gestures_remove(C); @@ -916,7 +917,7 @@ static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, if (ABS(data->dragstartx - event->x) + ABS(data->dragstarty - event->y) > U.dragthreshold) { button_activate_state(C, but, BUTTON_STATE_EXIT); - data->cancel = TRUE; + data->cancel = true; #ifdef USE_DRAG_TOGGLE if (ui_is_but_bool(but)) { uiDragToggleHandle *drag_info = MEM_callocN(sizeof(*drag_info), __func__); @@ -941,10 +942,10 @@ static int ui_but_start_drag(bContext *C, uiBut *but, uiHandleButtonData *data, if (but->imb) WM_event_drag_image(drag, but->imb, but->imb_scale, BLI_rctf_size_x(&but->rect), BLI_rctf_size_y(&but->rect)); } - return 1; + return true; } - return 0; + return false; } /* ********************** linklines *********************** */ @@ -1159,39 +1160,39 @@ static void ui_apply_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data) ui_apply_but_func(C, but); data->retval = but->retval; } - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_IMAGE(bContext *C, uiBut *but, uiHandleButtonData *data) { ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_HISTOGRAM(bContext *C, uiBut *but, uiHandleButtonData *data) { ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_WAVEFORM(bContext *C, uiBut *but, uiHandleButtonData *data) { ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } static void ui_apply_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data) { ui_apply_but_func(C, but); data->retval = but->retval; - data->applied = TRUE; + data->applied = true; } -static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, int interactive) +static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const bool interactive) { char *editstr; double *editval; @@ -1219,9 +1220,9 @@ static void ui_apply_button(bContext *C, uiBlock *block, uiBut *but, uiHandleBut /* we avoid applying interactive edits a second time * at the end with the appliedinteractive flag */ if (interactive) { - data->appliedinteractive = TRUE; + data->applied_interactive = true; } - else if (data->appliedinteractive) { + else if (data->applied_interactive) { return; } } @@ -1465,7 +1466,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); BLI_strncpy(buf, active_data->str, UI_MAX_DRAW_STR); WM_clipboard_text_set(active_data->str, 0); - active_data->cancel = TRUE; + active_data->cancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } else { @@ -1476,7 +1477,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { /* else uiSearchboxData.active member is not updated [#26856] */ - ui_searchbox_update(C, data->searchbox, but, 1); + ui_searchbox_update(C, data->searchbox, but, true); } button_activate_state(C, but, BUTTON_STATE_EXIT); } @@ -1585,14 +1586,14 @@ void ui_button_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but /* ************* in-button text selection/editing ************* */ -static int ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data) +static bool ui_textedit_delete_selection(uiBut *but, uiHandleButtonData *data) { char *str = data->str; - int len = strlen(str); - int change = 0; + const int len = strlen(str); + bool change = false; if (but->selsta != but->selend && len) { memmove(str + but->selsta, str + but->selend, (len - but->selend) + 1); - change = 1; + change = true; } but->pos = but->selend = but->selsta; @@ -1713,11 +1714,12 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data, /* this is used for both utf8 and ascii, its meant to be used for single keys, * notice the buffer is either copied or not, so its not suitable for pasting in * - campbell */ -static int ui_textedit_type_buf(uiBut *but, uiHandleButtonData *data, - const char *utf8_buf, int utf8_buf_len) +static bool ui_textedit_type_buf(uiBut *but, uiHandleButtonData *data, + const char *utf8_buf, int utf8_buf_len) { char *str; - int len, changed = 0; + int len; + bool changed = false; str = data->str; len = strlen(str); @@ -1735,14 +1737,14 @@ static int ui_textedit_type_buf(uiBut *but, uiHandleButtonData *data, memmove(&str[but->pos + step], &str[but->pos], (len + 1) - but->pos); memcpy(&str[but->pos], utf8_buf, step * sizeof(char)); but->pos += step; - changed = 1; + changed = true; } } return changed; } -static int ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char ascii) +static bool ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char ascii) { char buf[2] = {ascii, '\0'}; @@ -1750,7 +1752,7 @@ static int ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char asc printf("%s: entering invalid ascii char into an ascii key (%d)\n", __func__, (int)(unsigned char)ascii); - return 0; + return false; } /* in some cases we want to allow invalid utf8 chars */ @@ -1834,15 +1836,15 @@ static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, strCursorJump } } -static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int direction, strCursorJumpType jump) +static bool ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int direction, strCursorJumpType jump) { char *str = data->str; const int len = strlen(str); - int changed = 0; + bool changed = false; if (jump == STRCUR_JUMP_ALL) { - if (len) changed = 1; + if (len) changed = true; str[0] = '\0'; but->pos = 0; } @@ -1856,7 +1858,7 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio BLI_str_cursor_step_utf8(str, len, &pos, direction, jump, true); step = pos - but->pos; memmove(&str[but->pos], &str[but->pos + step], (len + 1) - but->pos); - changed = 1; + changed = true; } } else { /* backspace */ @@ -1872,7 +1874,7 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio step = but->pos - pos; memmove(&str[but->pos - step], &str[but->pos], (len + 1) - but->pos); but->pos -= step; - changed = 1; + changed = true; } } } @@ -1880,10 +1882,11 @@ static int ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directio return changed; } -static int ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData *data) +static bool ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData *data) { char *str; - int changed = 1; + /* TODO, should return false if it cant autocomp. */ + bool changed = true; str = data->str; @@ -1898,18 +1901,26 @@ static int ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData return changed; } -static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste, int copy, int cut) +/* mode for ui_textedit_copypaste() */ +enum { + UI_TEXTEDIT_PASTE = 1, + UI_TEXTEDIT_COPY, + UI_TEXTEDIT_CUT +}; + +static bool ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, const int mode) { char buf[UI_MAX_DRAW_STR] = {0}; char *str, *p, *pbuf; - int x, changed = 0; + int x; + bool changed = false; int str_len, buf_len; str = data->str; str_len = strlen(str); /* paste */ - if (paste) { + if (mode == UI_TEXTEDIT_PASTE) { /* TODO, ensure UTF8 ui_is_but_utf8() - campbell */ /* extract the first line from the clipboard */ p = pbuf = WM_clipboard_text_get(0); @@ -1941,7 +1952,7 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste } } - changed = 1; + changed = true; } if (pbuf) { @@ -1949,7 +1960,7 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste } } /* cut & copy */ - else if (copy || cut) { + else if (ELEM(mode, UI_TEXTEDIT_COPY, UI_TEXTEDIT_CUT)) { /* copy the contents to the copypaste buffer */ for (x = but->selsta; x <= but->selend; x++) { if (x == but->selend) @@ -1961,9 +1972,11 @@ static int ui_textedit_copypaste(uiBut *but, uiHandleButtonData *data, int paste WM_clipboard_text_set(buf, 0); /* for cut only, delete the selection afterwards */ - if (cut) - if ((but->selend - but->selsta) > 0) + if (mode == UI_TEXTEDIT_CUT) { + if ((but->selend - but->selsta) > 0) { changed = ui_textedit_delete_selection(but, data); + } + } } return changed; @@ -2007,7 +2020,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data) /* optional searchbox */ if (ELEM(but->type, SEARCH_MENU, SEARCH_MENU_UNLINK)) { data->searchbox = ui_searchbox_create(C, data->region, but); - ui_searchbox_update(C, data->searchbox, but, 1); /* 1 = reset */ + ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */ } ui_check_but(but); @@ -2028,7 +2041,7 @@ static void ui_textedit_end(bContext *C, uiBut *but, uiHandleButtonData *data) } if (data->searchbox) { - if (data->cancel == 0) + if (data->cancel == false) ui_searchbox_apply(but, data->searchbox); ui_searchbox_free(C, data->searchbox); @@ -2101,7 +2114,8 @@ static void ui_textedit_prev_but(uiBlock *block, uiBut *actbut, uiHandleButtonDa static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my, changed = 0, inbox = 0, update = 0, retval = WM_UI_HANDLER_CONTINUE; + int mx, my, retval = WM_UI_HANDLER_CONTINUE; + bool changed = false, inbox = false, update = false; switch (event->type) { case WHEELUPMOUSE: @@ -2114,8 +2128,8 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle break; case RIGHTMOUSE: case ESCKEY: - data->cancel = TRUE; - data->escapecancel = TRUE; + data->cancel = true; + data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); retval = WM_UI_HANDLER_BREAK; break; @@ -2138,10 +2152,10 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle button_activate_state(C, but, BUTTON_STATE_TEXT_SELECTING); retval = WM_UI_HANDLER_BREAK; } - else if (inbox == 0) { + else if (inbox == false) { /* if searchbox, click outside will cancel */ if (data->searchbox) - data->cancel = data->escapecancel = TRUE; + data->cancel = data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); retval = WM_UI_HANDLER_BREAK; } @@ -2161,11 +2175,11 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle case CKEY: if (event->ctrl || event->oskey) { if (event->type == VKEY) - changed = ui_textedit_copypaste(but, data, 1, 0, 0); + changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_PASTE); else if (event->type == CKEY) - changed = ui_textedit_copypaste(but, data, 0, 1, 0); + changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_COPY); else if (event->type == XKEY) - changed = ui_textedit_copypaste(but, data, 0, 0, 1); + changed = ui_textedit_copypaste(but, data, UI_TEXTEDIT_CUT); retval = WM_UI_HANDLER_BREAK; } @@ -2223,7 +2237,7 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle /* there is a key conflict here, we can't tab with autocomplete */ if (but->autocomplete_func || data->searchbox) { changed = ui_textedit_autocomplete(C, but, data); - update = 1; /* do live update for tab key */ + update = true; /* do live update for tab key */ } /* the hotkey here is not well defined, was G.qual so we check all */ else if (event->shift || event->ctrl || event->alt || event->oskey) { @@ -2270,21 +2284,21 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle } /* textbutton with magnifier icon: do live update for search button */ if (but->icon == ICON_VIEWZOOM) - update = 1; + update = true; } if (changed) { /* only update when typing for TAB key */ if (update && data->interactive) { - ui_apply_button(C, block, but, data, 1); + ui_apply_button(C, block, but, data, true); } else { ui_check_but(but); } - but->changed = TRUE; + but->changed = true; if (data->searchbox) - ui_searchbox_update(C, data->searchbox, but, 1); /* 1 = reset */ + ui_searchbox_update(C, data->searchbox, but, true); /* true = reset */ } if (changed || (retval == WM_UI_HANDLER_BREAK)) @@ -2351,8 +2365,8 @@ static void ui_numedit_begin(uiBut *but, uiHandleButtonData *data) data->dragf = data->dragfstart; } - data->dragchange = 0; - data->draglock = 1; + data->dragchange = false; + data->draglock = true; } static void ui_numedit_end(uiBut *but, uiHandleButtonData *data) @@ -2364,7 +2378,7 @@ static void ui_numedit_end(uiBut *but, uiHandleButtonData *data) data->dragstartx = 0; data->draglastx = 0; - data->dragchange = 0; + data->dragchange = false; data->dragcbd = NULL; data->dragsel = 0; } @@ -2372,7 +2386,7 @@ static void ui_numedit_end(uiBut *but, uiHandleButtonData *data) static void ui_numedit_apply(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data) { if (data->interactive) { - ui_apply_button(C, block, but, data, 1); + ui_apply_button(C, block, but, data, true); } else { ui_check_but(but); @@ -2499,7 +2513,7 @@ static int ui_do_but_BUT(bContext *C, uiBut *but, uiHandleButtonData *data, cons else if (data->state == BUTTON_STATE_WAIT_RELEASE) { if (event->type == LEFTMOUSE && event->val != KM_PRESS) { if (!(but->flag & UI_SELECT)) - data->cancel = TRUE; + data->cancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; } @@ -2530,7 +2544,7 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data if (but->flag & UI_BUT_IMMEDIATE) ui_set_but_val(but, 0); else - data->cancel = TRUE; + data->cancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; } @@ -2552,14 +2566,14 @@ static int ui_do_but_HOTKEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data if (WM_key_event_string(event->type)[0]) ui_set_but_val(but, event->type); else - data->cancel = TRUE; + data->cancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; } else if (event->type == ESCKEY) { - data->cancel = TRUE; - data->escapecancel = TRUE; + data->cancel = true; + data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } @@ -2585,7 +2599,7 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, c if (WM_key_event_string(event->type)[0]) ui_set_but_val(but, event->type); else - data->cancel = TRUE; + data->cancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } @@ -2803,10 +2817,11 @@ static float ui_numedit_apply_snap(int temp, float softmin, float softmax, int s return temp; } -static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx) +static bool ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, int snap, int mx) { float deler, tempf, softmin, softmax, softrange; - int lvalue, temp, changed = 0; + int lvalue, temp; + bool changed = false; const bool is_float = ui_is_but_float(but); if (mx == data->draglastx) @@ -2818,7 +2833,7 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i if (abs(mx - data->dragstartx) <= 3) return changed; - data->draglock = 0; + data->draglock = false; data->dragstartx = mx; /* ignore mouse movement within drag-lock */ } @@ -2848,9 +2863,9 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i #endif if (tempf != (float)data->value) { - data->dragchange = 1; + data->dragchange = true; data->value = tempf; - changed = 1; + changed = true; } } else { @@ -2875,9 +2890,9 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i #endif if (temp != data->value) { - data->dragchange = 1; + data->dragchange = true; data->value = temp; - changed = 1; + changed = true; } } @@ -2921,9 +2936,9 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i lvalue = (int)data->value; if (temp != lvalue) { - data->dragchange = 1; + data->dragchange = true; data->value = (double)temp; - changed = 1; + changed = true; } } else { @@ -2933,9 +2948,9 @@ static int ui_numedit_but_NUM(uiBut *but, uiHandleButtonData *data, float fac, i CLAMP(tempf, softmin, softmax); if (tempf != (float)data->value) { - data->dragchange = 1; + data->dragchange = true; data->value = tempf; - changed = 1; + changed = true; } } } @@ -2998,8 +3013,8 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton } else if (data->state == BUTTON_STATE_NUM_EDITING) { if (event->type == ESCKEY || event->type == RIGHTMOUSE) { - data->cancel = TRUE; - data->escapecancel = TRUE; + data->cancel = true; + data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } else if (event->type == LEFTMOUSE && event->val != KM_PRESS) { @@ -3049,7 +3064,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton if (temp >= softmin && temp <= softmax) data->value = (double)temp; else - data->cancel = TRUE; + data->cancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } @@ -3060,7 +3075,7 @@ static int ui_do_but_NUM(bContext *C, uiBlock *block, uiBut *but, uiHandleButton if (temp >= softmin && temp <= softmax) data->value = (double)temp; else - data->cancel = TRUE; + data->cancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } @@ -3185,7 +3200,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, if (temp != lvalue) { data->value = temp; - data->dragchange = 1; + data->dragchange = true; changed = true; } } @@ -3194,7 +3209,7 @@ static bool ui_numedit_but_SLI(uiBut *but, uiHandleButtonData *data, if (tempf != (float)data->value) { data->value = tempf; - data->dragchange = 1; + data->dragchange = true; changed = true; } } @@ -3321,7 +3336,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton if (temp >= softmin && temp <= softmax) data->value = temp; else - data->cancel = TRUE; + data->cancel = true; } else { if (f < tempf) tempf -= 0.01f; @@ -3330,7 +3345,7 @@ static int ui_do_but_SLI(bContext *C, uiBlock *block, uiBut *but, uiHandleButton if (tempf >= softmin && tempf <= softmax) data->value = tempf; else - data->cancel = TRUE; + data->cancel = true; } button_activate_state(C, but, BUTTON_STATE_EXIT); @@ -3379,8 +3394,8 @@ static int ui_do_but_SCROLL(bContext *C, uiBlock *block, uiBut *but, uiHandleBut } else if (data->state == BUTTON_STATE_NUM_EDITING) { if (event->type == ESCKEY) { - data->cancel = TRUE; - data->escapecancel = TRUE; + data->cancel = true; + data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } else if (event->type == LEFTMOUSE && event->val != KM_PRESS) { @@ -3432,7 +3447,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co data->value = ui_step_name_menu(but, direction); button_activate_state(C, but, BUTTON_STATE_EXIT); - ui_apply_button(C, but->block, but, data, 1); + ui_apply_button(C, but->block, but, data, true); /* button's state need to be changed to EXIT so moving mouse away from this mouse wouldn't lead * to cancel changes made to this button, but changing state to EXIT also makes no button active for @@ -3478,7 +3493,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co ui_set_but_vectorf(but, data->vec); button_activate_state(C, but, BUTTON_STATE_EXIT); - ui_apply_button(C, but->block, but, data, 1); + ui_apply_button(C, but->block, but, data, true); return WM_UI_HANDLER_BREAK; } } @@ -3493,7 +3508,7 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co /* outside icon quit, not needed if drag activated */ if (0 == ui_but_mouse_inside_icon(but, data->region, event)) { button_activate_state(C, but, BUTTON_STATE_EXIT); - data->cancel = TRUE; + data->cancel = true; return WM_UI_HANDLER_BREAK; } @@ -3507,10 +3522,11 @@ static int ui_do_but_BLOCK(bContext *C, uiBut *but, uiHandleButtonData *data, co return WM_UI_HANDLER_CONTINUE; } -static int ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, int my) +static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data, int mx, int my) { float dx, dy, rad, radsq, mrad, *fp; - int mdx, mdy, changed = 1; + int mdx, mdy; + bool changed = true; /* button is presumed square */ /* if mouse moves outside of sphere, it does negative normal */ @@ -3621,13 +3637,13 @@ static void clamp_axis_max_v3(float v[3], const float max) } } -static int ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my, const short shift) +static bool ui_numedit_but_HSVCUBE(uiBut *but, uiHandleButtonData *data, int mx, int my, const short shift) { float rgb[3]; float *hsv = ui_block_hsv_get(but->block); float x, y; float mx_fl, my_fl; - int changed = 1; + bool changed = true; int color_profile = but->block->color_profile; ui_mouse_scale_warp(data, mx, my, &mx_fl, &my_fl, shift); @@ -3800,7 +3816,7 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu ui_ndofedit_but_HSVCUBE(but, data, ndof, event->shift); button_activate_state(C, but, BUTTON_STATE_EXIT); - ui_apply_button(C, but->block, but, data, 1); + ui_apply_button(C, but->block, but, data, true); return WM_UI_HANDLER_BREAK; } @@ -3840,8 +3856,8 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu } else if (data->state == BUTTON_STATE_NUM_EDITING) { if (event->type == ESCKEY || event->type == RIGHTMOUSE) { - data->cancel = TRUE; - data->escapecancel = TRUE; + data->cancel = true; + data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } else if (event->type == MOUSEMOVE) { @@ -3860,10 +3876,10 @@ static int ui_do_but_HSVCUBE(bContext *C, uiBlock *block, uiBut *but, uiHandleBu return WM_UI_HANDLER_CONTINUE; } -static int ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float mx, float my, int shift) +static bool ui_numedit_but_HSVCIRCLE(uiBut *but, uiHandleButtonData *data, float mx, float my, int shift) { rcti rect; - int changed = 1; + bool changed = true; float mx_fl, my_fl; float rgb[3]; float hsv[3]; @@ -3999,7 +4015,7 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle ui_ndofedit_but_HSVCIRCLE(but, data, ndof, event->shift); button_activate_state(C, but, BUTTON_STATE_EXIT); - ui_apply_button(C, but->block, but, data, 1); + ui_apply_button(C, but->block, but, data, true); return WM_UI_HANDLER_BREAK; } @@ -4037,8 +4053,8 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle } else if (data->state == BUTTON_STATE_NUM_EDITING) { if (event->type == ESCKEY || event->type == RIGHTMOUSE) { - data->cancel = TRUE; - data->escapecancel = TRUE; + data->cancel = true; + data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } /* XXX hardcoded keymap check.... */ @@ -4070,10 +4086,10 @@ static int ui_do_but_HSVCIRCLE(bContext *C, uiBlock *block, uiBut *but, uiHandle } -static int ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int mx) +static bool ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int mx) { float dx; - int changed = 0; + bool changed = false; if (data->draglastx == mx) return changed; @@ -4086,7 +4102,7 @@ static int ui_numedit_but_COLORBAND(uiBut *but, uiHandleButtonData *data, int mx data->dragcbd = data->coba->data + data->coba->cur; /* because qsort */ data->draglastx = mx; - changed = 1; + changed = true; return changed; } @@ -4152,7 +4168,7 @@ static int ui_do_but_COLORBAND(bContext *C, uiBlock *block, uiBut *but, uiHandle return WM_UI_HANDLER_CONTINUE; } -static int ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData *data, int snap, +static bool ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData *data, int snap, int evtx, int evty, const short shift) { CurveMapping *cumap = (CurveMapping *)but->poin; @@ -4160,7 +4176,8 @@ static int ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData * CurveMapPoint *cmp = cuma->curve; float fx, fy, zoomx, zoomy; int mx, my, dragx, dragy; - int a, changed = 0; + int a; + bool changed = false; /* evtx evty and drag coords are absolute mousecoords, prevents errors when editing when layout changes */ mx = evtx; @@ -4215,7 +4232,7 @@ static int ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData * if (moved_point) { data->draglastx = evtx; data->draglasty = evty; - changed = 1; + changed = true; #ifdef USE_CONT_MOUSE_CORRECT /* note: using 'cmp_last' is weak since there may be multiple points selected, @@ -4230,7 +4247,7 @@ static int ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData * } - data->dragchange = 1; /* mark for selection */ + data->dragchange = true; /* mark for selection */ } else { fx = (mx - dragx) / zoomx; @@ -4256,7 +4273,7 @@ static int ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData * data->draglastx = evtx; data->draglasty = evty; - changed = 1; + changed = true; } return changed; @@ -4264,7 +4281,8 @@ static int ui_numedit_but_CURVE(uiBlock *block, uiBut *but, uiHandleButtonData * static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButtonData *data, const wmEvent *event) { - int mx, my, a, changed = 0; + int mx, my, a; + bool changed = false; mx = event->x; my = event->y; @@ -4290,7 +4308,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt curvemap_insert(cuma, fx, fy); curvemapping_changed(cumap, FALSE); - changed = 1; + changed = true; } /* check for selecting of a point */ @@ -4325,7 +4343,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt curvemap_insert(cuma, fx, fy); curvemapping_changed(cumap, FALSE); - changed = 1; + changed = true; /* reset cmp back to the curve points again, rather than drawing segments */ cmp = cuma->curve; @@ -4355,7 +4373,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt } else { /* move the view */ - data->cancel = TRUE; + data->cancel = true; } data->dragsel = sel; @@ -4383,7 +4401,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt CurveMap *cuma = cumap->cm + cumap->cur; CurveMapPoint *cmp = cuma->curve; - if (!data->dragchange) { + if (data->dragchange == false) { /* deselect all, select one */ if (event->shift == FALSE) { for (a = 0; a < cuma->totpoint; a++) @@ -4392,7 +4410,7 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt } } else { - curvemapping_changed(cumap, TRUE); /* remove doubles */ + curvemapping_changed(cumap, true); /* remove doubles */ } } @@ -4408,17 +4426,17 @@ static int ui_do_but_CURVE(bContext *C, uiBlock *block, uiBut *but, uiHandleButt return WM_UI_HANDLER_CONTINUE; } -static int in_scope_resize_zone(uiBut *but, int UNUSED(x), int y) +static bool in_scope_resize_zone(uiBut *but, int UNUSED(x), int y) { /* bottom corner return (x > but->rect.xmax - SCOPE_RESIZE_PAD) && (y < but->rect.ymin + SCOPE_RESIZE_PAD); */ return (y < but->rect.ymin + SCOPE_RESIZE_PAD); } -static int ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx, int my) +static bool ui_numedit_but_HISTOGRAM(uiBut *but, uiHandleButtonData *data, int mx, int my) { Histogram *hist = (Histogram *)but->poin; /* rcti rect; */ - int changed = 1; + bool changed = true; float /* dx, */ dy; /* UNUSED */ /* BLI_rcti_rctf_copy(&rect, &but->rect); */ @@ -4478,8 +4496,8 @@ static int ui_do_but_HISTOGRAM(bContext *C, uiBlock *block, uiBut *but, uiHandle } else if (data->state == BUTTON_STATE_NUM_EDITING) { if (event->type == ESCKEY) { - data->cancel = TRUE; - data->escapecancel = TRUE; + data->cancel = true; + data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } else if (event->type == MOUSEMOVE) { @@ -4497,11 +4515,11 @@ static int ui_do_but_HISTOGRAM(bContext *C, uiBlock *block, uiBut *but, uiHandle return WM_UI_HANDLER_CONTINUE; } -static int ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, int my) +static bool ui_numedit_but_WAVEFORM(uiBut *but, uiHandleButtonData *data, int mx, int my) { Scopes *scopes = (Scopes *)but->poin; /* rcti rect; */ - int changed = 1; + bool changed = true; float /* dx, */ dy /* , yfac =1.0f */; /* UNUSED */ /* BLI_rcti_rctf_copy(&rect, &but->rect); */ @@ -4561,8 +4579,8 @@ static int ui_do_but_WAVEFORM(bContext *C, uiBlock *block, uiBut *but, uiHandleB } else if (data->state == BUTTON_STATE_NUM_EDITING) { if (event->type == ESCKEY) { - data->cancel = TRUE; - data->escapecancel = TRUE; + data->cancel = true; + data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } else if (event->type == MOUSEMOVE) { @@ -4580,11 +4598,11 @@ static int ui_do_but_WAVEFORM(bContext *C, uiBlock *block, uiBut *but, uiHandleB return WM_UI_HANDLER_CONTINUE; } -static int ui_numedit_but_VECTORSCOPE(uiBut *but, uiHandleButtonData *data, int mx, int my) +static bool ui_numedit_but_VECTORSCOPE(uiBut *but, uiHandleButtonData *data, int mx, int my) { Scopes *scopes = (Scopes *)but->poin; /* rcti rect; */ - int changed = 1; + bool changed = true; /* float dx, dy; */ /* BLI_rcti_rctf_copy(&rect, &but->rect); */ @@ -4628,8 +4646,8 @@ static int ui_do_but_VECTORSCOPE(bContext *C, uiBlock *block, uiBut *but, uiHand } else if (data->state == BUTTON_STATE_NUM_EDITING) { if (event->type == ESCKEY) { - data->cancel = TRUE; - data->escapecancel = TRUE; + data->cancel = true; + data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } else if (event->type == MOUSEMOVE) { @@ -4771,7 +4789,7 @@ static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, con if (event->type == LEFTMOUSE && event->val != KM_PRESS) { if (!(but->flag & UI_SELECT)) - data->cancel = TRUE; + data->cancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); return WM_UI_HANDLER_BREAK; } @@ -4780,11 +4798,11 @@ static int ui_do_but_LINK(bContext *C, uiBut *but, uiHandleButtonData *data, con return WM_UI_HANDLER_CONTINUE; } -static int ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data, - int mx, int my, const short shift) +static bool ui_numedit_but_TRACKPREVIEW(bContext *C, uiBut *but, uiHandleButtonData *data, + int mx, int my, const short shift) { MovieClipScopes *scopes = (MovieClipScopes *)but->poin; - int changed = 1; + bool changed = true; float dx, dy; dx = mx - data->draglastx; @@ -4845,8 +4863,8 @@ static int ui_do_but_TRACKPREVIEW(bContext *C, uiBlock *block, uiBut *but, uiHan } else if (data->state == BUTTON_STATE_NUM_EDITING) { if (event->type == ESCKEY) { - data->cancel = TRUE; - data->escapecancel = TRUE; + data->cancel = true; + data->escapecancel = true; button_activate_state(C, but, BUTTON_STATE_EXIT); } else if (event->type == MOUSEMOVE) { @@ -4874,14 +4892,14 @@ static void but_shortcut_name_func(bContext *C, void *arg1, int UNUSED(event)) IDProperty *prop = (but->opptr) ? but->opptr->data : NULL; /* complex code to change name of button */ - if (WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, TRUE, + if (WM_key_event_operator_string(C, but->optype->idname, but->opcontext, prop, true, shortcut_str, sizeof(shortcut_str))) { - ui_but_add_shortcut(but, shortcut_str, TRUE); + ui_but_add_shortcut(but, shortcut_str, true); } else { /* simply strip the shortcut */ - ui_but_add_shortcut(but, NULL, TRUE); + ui_but_add_shortcut(but, NULL, true); } } } @@ -4992,7 +5010,7 @@ static void popup_add_shortcut_func(bContext *C, void *arg1, void *UNUSED(arg2)) } -static int ui_but_menu(bContext *C, uiBut *but) +static bool ui_but_menu(bContext *C, uiBut *but) { uiPopupMenu *pup; uiLayout *layout; @@ -5002,6 +5020,11 @@ static int ui_but_menu(bContext *C, uiBut *but) /* if ((but->rnapoin.data && but->rnaprop) == 0 && but->optype == NULL)*/ /* return 0;*/ + + /* having this menu for some buttons makes no sense */ + if (but->type == BUT_IMAGE) { + return false; + } button_timers_tooltip_remove(C, but); @@ -5279,7 +5302,7 @@ static int ui_but_menu(bContext *C, uiBut *but) uiPupMenuEnd(C, pup); - return 1; + return true; } static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *event) @@ -5372,7 +5395,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent * /* verify if we can edit this button */ if (ELEM(event->type, LEFTMOUSE, RETKEY)) { /* this should become disabled button .. */ - if (but->lock == TRUE) { + if (but->lock == true) { if (but->lockstr) { BKE_report(NULL, RPT_WARNING, but->lockstr); button_activate_state(C, but, BUTTON_STATE_EXIT); @@ -5552,7 +5575,7 @@ void uiFreeActiveButtons(const bContext *C, bScreen *screen) -/* returns TRUE if highlighted button allows drop of names */ +/* returns true if highlighted button allows drop of names */ /* called in region context */ int UI_but_active_drop_name(bContext *C) { @@ -5567,7 +5590,7 @@ int UI_but_active_drop_name(bContext *C) return 0; } -static void ui_blocks_set_tooltips(ARegion *ar, int enable) +static void ui_blocks_set_tooltips(ARegion *ar, const bool enable) { uiBlock *block; @@ -5707,7 +5730,7 @@ static uiBut *ui_list_find_mouse_over(ARegion *ar, int x, int y) /* ****************** button state handling **************************/ -static int button_modal_state(uiHandleButtonState state) +static bool button_modal_state(uiHandleButtonState state) { return ELEM6(state, BUTTON_STATE_WAIT_RELEASE, BUTTON_STATE_WAIT_KEY_EVENT, BUTTON_STATE_NUM_EDITING, BUTTON_STATE_TEXT_EDITING, @@ -5774,10 +5797,10 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s if (data->used_mouse && !data->autoopentimer) { int time; - if (but->block->auto_open == TRUE) { /* test for toolbox */ + if (but->block->auto_open == true) { /* test for toolbox */ time = 1; } - else if ((but->block->flag & UI_BLOCK_LOOP && but->type != BLOCK) || but->block->auto_open == TRUE) { + else if ((but->block->flag & UI_BLOCK_LOOP && but->type != BLOCK) || but->block->auto_open == true) { time = 5 * U.menuthreshold2; } else if (U.uiflag & USER_MENUOPENAUTO) { @@ -5809,7 +5832,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s /* number editing */ if (state == BUTTON_STATE_NUM_EDITING) { if (ui_is_a_warp_but(but)) - WM_cursor_grab_enable(CTX_wm_window(C), TRUE, TRUE, NULL); + WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL); ui_numedit_begin(but, data); } else if (data->state == BUTTON_STATE_NUM_EDITING) { @@ -5857,8 +5880,8 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s } else { if (button_modal_state(data->state)) { - /* TRUE = postpone free */ - WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data, TRUE); + /* true = postpone free */ + WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data, true); } } } @@ -5902,7 +5925,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA /* XXX curve is temp */ } else { - data->interactive = TRUE; + data->interactive = true; } data->state = BUTTON_STATE_INIT; @@ -5914,12 +5937,12 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA /* we disable auto_open in the block after a threshold, because we still * want to allow auto opening adjacent menus even if no button is activated * in between going over to the other button, but only for a short while */ - if (type == BUTTON_ACTIVATE_OVER && but->block->auto_open == TRUE) + if (type == BUTTON_ACTIVATE_OVER && but->block->auto_open == true) if (but->block->auto_open_last + BUTTON_AUTO_OPEN_THRESH < PIL_check_seconds_timer()) but->block->auto_open = FALSE; if (type == BUTTON_ACTIVATE_OVER) { - data->used_mouse = TRUE; + data->used_mouse = true; } button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT); @@ -5965,7 +5988,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da /* apply the button action or value */ if (!onfree) - ui_apply_button(C, block, but, data, 0); + ui_apply_button(C, block, but, data, false); /* if this button is in a menu, this will set the button return * value to the button value and the menu return value to ok, the @@ -5998,7 +6021,7 @@ static void button_activate_exit(bContext *C, uiBut *but, uiHandleButtonData *da block->tooltipdisabled = 1; } - ui_blocks_set_tooltips(data->region, 0); + ui_blocks_set_tooltips(data->region, false); /* clean up */ if (data->str) @@ -6042,7 +6065,7 @@ void ui_button_active_free(const bContext *C, uiBut *but) } /* returns the active button with an optional checking function */ -static uiBut *ui_context_button_active(const bContext *C, int (*but_check_cb)(uiBut *)) +static uiBut *ui_context_button_active(const bContext *C, bool (*but_check_cb)(uiBut *)) { uiBut *but_found = NULL; @@ -6084,7 +6107,7 @@ static uiBut *ui_context_button_active(const bContext *C, int (*but_check_cb)(ui return but_found; } -static int ui_context_rna_button_active_test(uiBut *but) +static bool ui_context_rna_button_active_test(uiBut *but) { return (but->rnapoin.data != NULL); } @@ -6328,7 +6351,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but) } else if (event->x != event->prevx || event->y != event->prevy) { /* re-enable tooltip on mouse move */ - ui_blocks_set_tooltips(ar, 1); + ui_blocks_set_tooltips(ar, true); button_tooltip_timer_reset(C, but); } @@ -6586,7 +6609,7 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u if (menu->menuretval & UI_RETURN_UPDATE) { if (data->interactive) { - ui_apply_button(C, but->block, but, data, TRUE); + ui_apply_button(C, but->block, but, data, true); } else { ui_check_but(but); @@ -6609,7 +6632,7 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u else { if (ISKEYBOARD(event->type)) { /* keyboard menu hierarchy navigation, going back to previous level */ - but->active->used_mouse = FALSE; + but->active->used_mouse = false; button_activate_state(C, but, BUTTON_STATE_HIGHLIGHT); } else { @@ -6631,10 +6654,10 @@ static void ui_handle_button_return_submenu(bContext *C, const wmEvent *event, u * - only for 1 second */ -static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, int mx, int my, int force) +static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, int mx, int my, const bool force) { if (!menu->dotowards || force) { - menu->dotowards = TRUE; + menu->dotowards = true; menu->towardsx = mx; menu->towardsy = my; @@ -6645,10 +6668,10 @@ static void ui_mouse_motion_towards_init(uiPopupBlockHandle *menu, int mx, int m } } -static int ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, int mx, int my) +static bool ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *menu, int mx, int my) { float p1[2], p2[2], p3[2], p4[2], oldp[2], newp[2]; - int closer; + bool closer; if (!menu->dotowards) { return 0; @@ -6684,11 +6707,11 @@ static int ui_mouse_motion_towards_check(uiBlock *block, uiPopupBlockHandle *men isect_point_tri_v2(newp, oldp, p4, p1)); if (!closer) - menu->dotowards = FALSE; + menu->dotowards = false; /* 1 second timer */ if (PIL_check_seconds_timer() - menu->towardstime > BUTTON_MOUSE_TOWARDS_THRESH) - menu->dotowards = FALSE; + menu->dotowards = false; return menu->dotowards; } @@ -6797,7 +6820,7 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH /* if a button is activated modal, always reset the start mouse * position of the towards mechanism to avoid loosing focus, * and don't handle events */ - ui_mouse_motion_towards_init(menu, mx, my, 1); + ui_mouse_motion_towards_init(menu, mx, my, true); } else if (event->type == TIMER) { if (event->customdata == menu->scrolltimer) @@ -6806,7 +6829,7 @@ static int ui_handle_menu_event(bContext *C, const wmEvent *event, uiPopupBlockH else { /* for ui_mouse_motion_towards_block */ if (event->type == MOUSEMOVE) { - ui_mouse_motion_towards_init(menu, mx, my, 0); + ui_mouse_motion_towards_init(menu, mx, my, false); /* add menu scroll timer, if needed */ if (ui_menu_scroll_test(block, my)) @@ -7223,7 +7246,7 @@ static int ui_handle_menu_return_submenu(bContext *C, const wmEvent *event, uiPo mx = event->x; my = event->y; ui_window_to_block(ar, block, &mx, &my); - ui_mouse_motion_towards_init(menu, mx, my, 1); + ui_mouse_motion_towards_init(menu, mx, my, true); if (menu->menuretval) return WM_UI_HANDLER_CONTINUE; @@ -7299,7 +7322,7 @@ static int ui_handler_region(bContext *C, const wmEvent *event, void *UNUSED(use /* re-enable tooltips */ if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) - ui_blocks_set_tooltips(ar, 1); + ui_blocks_set_tooltips(ar, true); /* delayed apply callbacks */ ui_apply_but_funcs_after(C); @@ -7372,7 +7395,7 @@ static int ui_handler_region_menu(bContext *C, const wmEvent *event, void *UNUSE /* re-enable tooltips */ if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) - ui_blocks_set_tooltips(ar, 1); + ui_blocks_set_tooltips(ar, true); /* delayed apply callbacks */ ui_apply_but_funcs_after(C); @@ -7420,7 +7443,7 @@ static int ui_handler_popup(bContext *C, const wmEvent *event, void *userdata) else { /* re-enable tooltips */ if (event->type == MOUSEMOVE && (event->x != event->prevx || event->y != event->prevy)) - ui_blocks_set_tooltips(menu->region, 1); + ui_blocks_set_tooltips(menu->region, true); } /* delayed apply callbacks */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 41ceeb141c9..91dc6dcab7e 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -424,9 +424,9 @@ struct uiPopupBlockHandle { struct ARegion *region; int towardsx, towardsy; double towardstime; - int dotowards; + bool dotowards; - int popup; + bool popup; void (*popup_func)(struct bContext *C, void *arg, int event); void (*cancel_func)(struct bContext *C, void *arg); void *popup_arg; @@ -465,7 +465,7 @@ void ui_popup_block_scrolltest(struct uiBlock *block); /* searchbox for string button */ ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBut *but); bool ui_searchbox_inside(struct ARegion *ar, int x, int y); -void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, int reset); +void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, const bool reset); void ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str); void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, const struct wmEvent *event); void ui_searchbox_apply(uiBut *but, struct ARegion *ar); @@ -556,7 +556,7 @@ void ui_resources_free(void); void ui_layout_add_but(uiLayout *layout, uiBut *but); int ui_but_can_align(uiBut *but); void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRNA *searchptr, PropertyRNA *searchprop); -void ui_but_add_shortcut(uiBut *but, const char *key_str, const short do_strip); +void ui_but_add_shortcut(uiBut *but, const char *key_str, const bool do_strip); /* interface_anim.c */ void ui_but_anim_flag(uiBut *but, float cfra); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 2ccba2e35f0..976033cd483 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -815,7 +815,7 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step) if (data->items.more) { data->items.offset++; data->active = data->items.totitem; - ui_searchbox_update(C, ar, but, 0); + ui_searchbox_update(C, ar, but, false); } else data->active = data->items.totitem; @@ -824,7 +824,7 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step) if (data->items.offset) { data->items.offset--; data->active = 1; - ui_searchbox_update(C, ar, but, 0); + ui_searchbox_update(C, ar, but, false); } else if (data->active < 0) data->active = 0; @@ -931,14 +931,14 @@ void ui_searchbox_event(bContext *C, ARegion *ar, uiBut *but, const wmEvent *eve } /* ar is the search box itself */ -void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, int reset) +void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) { uiSearchboxData *data = ar->regiondata; /* reset vars */ data->items.totitem = 0; data->items.more = 0; - if (reset == 0) { + if (reset == false) { data->items.offset_i = data->items.offset; } else { @@ -2481,7 +2481,7 @@ uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut handle = ui_popup_block_create(C, butregion, but, NULL, ui_block_func_POPUP, pup); if (!but) { - handle->popup = 1; + handle->popup = true; UI_add_popup_handlers(C, &window->modalhandlers, handle); WM_event_add_mousemove(C); @@ -2536,12 +2536,12 @@ void uiPupMenuEnd(bContext *C, uiPopupMenu *pup) wmWindow *window = CTX_wm_window(C); uiPopupBlockHandle *menu; - pup->popup = 1; + pup->popup = true; pup->mx = window->eventstate->x; pup->my = window->eventstate->y; menu = ui_popup_block_create(C, NULL, NULL, NULL, ui_block_func_POPUP, pup); - menu->popup = 1; + menu->popup = true; UI_add_popup_handlers(C, &window->modalhandlers, menu); WM_event_add_mousemove(C); @@ -2737,7 +2737,7 @@ void uiPupBlockO(bContext *C, uiBlockCreateFunc func, void *arg, const char *opn uiPopupBlockHandle *handle; handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg); - handle->popup = 1; + handle->popup = true; handle->optype = (opname) ? WM_operatortype_find(opname, 0) : NULL; handle->opcontext = opcontext; @@ -2756,7 +2756,7 @@ void uiPupBlockEx(bContext *C, uiBlockCreateFunc func, uiBlockHandleFunc popup_f uiPopupBlockHandle *handle; handle = ui_popup_block_create(C, NULL, NULL, func, NULL, arg); - handle->popup = 1; + handle->popup = true; handle->retvalue = 1; handle->popup_arg = arg; diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index dd575dbf522..634f686c9e6 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -2122,7 +2122,7 @@ static void curvemap_buttons_layout(uiLayout *layout, PointerRNA *ptr, char labe /* curve itself */ size = uiLayoutGetWidth(layout); row = uiLayoutRow(layout, FALSE); - uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, MIN2(size, 10.0f * UI_UNIT_X), cumap, 0.0f, 1.0f, bg, 0, ""); + uiDefBut(block, BUT_CURVE, 0, "", 0, 0, size, 8.0f * UI_UNIT_X, cumap, 0.0f, 1.0f, bg, 0, ""); /* sliders for selected point */ for (i = 0; i < cm->totpoint; i++) { diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index d6ae2497cbb..c12b2f57f1a 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -126,7 +126,7 @@ void paintface_flush_flags(Object *ob) } } -void paintface_hide(Object *ob, const int unselected) +void paintface_hide(Object *ob, const bool unselected) { Mesh *me; MPoly *mpoly; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 3dfa2fa5c6c..dab5adda790 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -104,7 +104,7 @@ void EDBM_select_mirrored(Object *UNUSED(obedit), BMEditMesh *em, bool extend) EDBM_verts_mirror_cache_end(em); } -void EDBM_automerge(Scene *scene, Object *obedit, int update) +void EDBM_automerge(Scene *scene, Object *obedit, bool update) { if ((scene->toolsettings->automerge) && @@ -377,13 +377,11 @@ static void findnearestvert__doClosest(void *userData, BMVert *eve, const float -static unsigned int findnearestvert__backbufIndextest(void *handle, unsigned int index) +static bool findnearestvert__backbufIndextest(void *handle, unsigned int index) { BMEditMesh *em = (BMEditMesh *)handle; BMVert *eve = BM_vert_at_index(em->bm, index - 1); - - if (eve && BM_elem_flag_test(eve, BM_ELEM_SELECT)) return 0; - return 1; + return !(eve && BM_elem_flag_test(eve, BM_ELEM_SELECT)); } /** * findnearestvert @@ -2346,7 +2344,7 @@ void EDBM_select_swap(BMEditMesh *em) /* exported for UV */ // if (EM_texFaceCheck()) } -int EDBM_select_interior_faces(BMEditMesh *em) +bool EDBM_select_interior_faces(BMEditMesh *em) { BMesh *bm = em->bm; BMIter iter; @@ -2954,7 +2952,7 @@ static void deselect_nth_active(BMEditMesh *em, BMVert **r_eve, BMEdge **r_eed, } } -static int edbm_deselect_nth(BMEditMesh *em, int nth, int offset) +static bool edbm_deselect_nth(BMEditMesh *em, int nth, int offset) { BMVert *v; BMEdge *e; @@ -2964,18 +2962,18 @@ static int edbm_deselect_nth(BMEditMesh *em, int nth, int offset) if (v) { walker_deselect_nth(em, nth, offset, &v->head); - return 1; + return true; } else if (e) { walker_deselect_nth(em, nth, offset, &e->head); - return 1; + return true; } else if (f) { walker_deselect_nth(em, nth, offset, &f->head); - return 1; + return true; } - return 0; + return false; } static int edbm_select_nth_exec(bContext *C, wmOperator *op) @@ -2988,7 +2986,7 @@ static int edbm_select_nth_exec(bContext *C, wmOperator *op) /* so input of offset zero ends up being (nth - 1) */ offset = (offset + (nth - 1)) % nth; - if (edbm_deselect_nth(em, nth, offset) == 0) { + if (edbm_deselect_nth(em, nth, offset) == false) { BKE_report(op->reports, RPT_ERROR, "Mesh has no active vert/edge/face"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 9020e133b33..5547df89463 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -816,7 +816,7 @@ UvMapVert *EDBM_uv_vert_map_at_index(UvVertMap *vmap, unsigned int v) /* A specialized vert map used by stitch operator */ -UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, int selected, int do_islands) +UvElementMap *EDBM_uv_element_map_create(BMEditMesh *em, const bool selected, const bool do_islands) { BMVert *ev; BMFace *efa; @@ -1070,7 +1070,7 @@ UvElement *ED_uv_element_get(UvElementMap *map, BMFace *efa, BMLoop *l) /* last_sel, use em->act_face otherwise get the last selected face in the editselections * at the moment, last_sel is mainly useful for making sure the space image dosnt flicker */ -MTexPoly *EDBM_mtexpoly_active_get(BMEditMesh *em, BMFace **r_act_efa, int sloppy, int selected) +MTexPoly *EDBM_mtexpoly_active_get(BMEditMesh *em, BMFace **r_act_efa, const bool sloppy, const bool selected) { BMFace *efa = NULL; @@ -1089,14 +1089,14 @@ MTexPoly *EDBM_mtexpoly_active_get(BMEditMesh *em, BMFace **r_act_efa, int slopp } /* can we edit UV's for this mesh?*/ -int EDBM_mtexpoly_check(BMEditMesh *em) +bool EDBM_mtexpoly_check(BMEditMesh *em) { /* some of these checks could be a touch overkill */ return em && em->bm->totface && CustomData_has_layer(&em->bm->pdata, CD_MTEXPOLY) && CustomData_has_layer(&em->bm->ldata, CD_MLOOPUV); } -int EDBM_vert_color_check(BMEditMesh *em) +bool EDBM_vert_color_check(BMEditMesh *em) { /* some of these checks could be a touch overkill */ return em && em->bm->totface && CustomData_has_layer(&em->bm->ldata, CD_MLOOPCOL); @@ -1265,11 +1265,12 @@ void EDBM_verts_mirror_apply(BMEditMesh *em, const int sel_from, const int sel_t /* swap is 0 or 1, if 1 it hides not selected */ -void EDBM_mesh_hide(BMEditMesh *em, int swap) +void EDBM_mesh_hide(BMEditMesh *em, bool swap) { BMIter iter; BMElem *ele; int itermode; + char hflag_swap = swap ? BM_ELEM_SELECT : 0; if (em == NULL) return; @@ -1281,7 +1282,7 @@ void EDBM_mesh_hide(BMEditMesh *em, int swap) itermode = BM_FACES_OF_MESH; BM_ITER_MESH (ele, &iter, em->bm, itermode) { - if (BM_elem_flag_test(ele, BM_ELEM_SELECT) ^ swap) + if (BM_elem_flag_test(ele, BM_ELEM_SELECT) ^ hflag_swap) BM_elem_hide_set(em->bm, ele, true); } diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index cbaa80718ee..97650b3a318 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -220,7 +220,7 @@ static void delete_customdata_layer(Mesh *me, CustomDataLayer *layer) } /* without bContext, called in uvedit */ -int ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum) +void ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum) { BMEditMesh *em = me->edit_btmesh; MLoopUV *luv; @@ -323,20 +323,16 @@ int ED_mesh_uv_loop_reset_ex(struct Mesh *me, const int layernum) BLI_array_free(polylengths); DAG_id_tag_update(&me->id, 0); - - return 1; } -int ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me) +void ED_mesh_uv_loop_reset(struct bContext *C, struct Mesh *me) { /* could be ldata or pdata */ CustomData *pdata = GET_CD_DATA(me, pdata); const int layernum = CustomData_get_active_layer_index(pdata, CD_MTEXPOLY); - int retval = ED_mesh_uv_loop_reset_ex(me, layernum); + ED_mesh_uv_loop_reset_ex(me, layernum); WM_event_add_notifier(C, NC_GEOM | ND_DATA, me); - - return retval; } /* note: keep in sync with ED_mesh_color_add */ diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index cdc920ba3ec..e242dbfde85 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -549,7 +549,7 @@ void OBJECT_OT_parent_clear(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - ot->prop = RNA_def_enum(ot->srna, "type", prop_clear_parent_types, 0, "Type", ""); + ot->prop = RNA_def_enum(ot->srna, "type", prop_clear_parent_types, CLEAR_PARENT_ALL, "Type", ""); } /* ******************** Make Parent Operator *********************** */ diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index bdf04dcd20d..a9fac006486 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -84,18 +84,18 @@ static void vgroup_remap_update_users(Object *ob, int *map); static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup); static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg); static void vgroup_delete_all(Object *ob); -static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, const short use_vert_sel); +static bool ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, const bool use_vert_sel); -static int vertex_group_use_vert_sel(Object *ob) +static bool vertex_group_use_vert_sel(Object *ob) { if (ob->mode == OB_MODE_EDIT) { - return TRUE; + return true; } else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_PAINT_VERT_SEL) { - return TRUE; + return true; } else { - return FALSE; + return false; } } @@ -106,14 +106,14 @@ static Lattice *vgroup_edit_lattice(Object *ob) return (lt->editlatt) ? lt->editlatt->latt : lt; } -int ED_vgroup_object_is_edit_mode(Object *ob) +bool ED_vgroup_object_is_edit_mode(Object *ob) { if (ob->type == OB_MESH) return (BMEdit_FromObject(ob) != NULL); else if (ob->type == OB_LATTICE) return (((Lattice *)ob->data)->editlatt != NULL); - return 0; + return false; } bDeformGroup *ED_vgroup_add_name(Object *ob, const char *name) @@ -167,22 +167,22 @@ void ED_vgroup_clear(Object *ob) } } -int ED_vgroup_data_create(ID *id) +bool ED_vgroup_data_create(ID *id) { /* create deform verts */ if (GS(id->name) == ID_ME) { Mesh *me = (Mesh *)id; me->dvert = CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert); - return TRUE; + return true; } else if (GS(id->name) == ID_LT) { Lattice *lt = (Lattice *)id; lt->dvert = MEM_callocN(sizeof(MDeformVert) * lt->pntsu * lt->pntsv * lt->pntsw, "lattice deformVert"); - return TRUE; + return true; } else { - return FALSE; + return false; } } @@ -209,7 +209,7 @@ void ED_vgroup_data_clamp_range(ID *id, const int total) } } -static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, const short use_vert_sel) +static bool ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot, const bool use_vert_sel) { *dvert_tot = 0; *dvert_arr = NULL; @@ -227,7 +227,7 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to int i; if (!CustomData_has_layer(&em->bm->vdata, CD_MDEFORMVERT)) { - return 0; + return false; } i = em->bm->totvert; @@ -250,7 +250,7 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to } } - return 1; + return true; } else if (me->dvert) { MVert *mvert = me->mvert; @@ -272,10 +272,10 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to } } - return 1; + return true; } else { - return 0; + return false; } } case ID_LT: @@ -302,20 +302,20 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to } } - return 1; + return true; } else { - return 0; + return false; } } } } - return 0; + return false; } /* returns true if the id type supports weights */ -int ED_vgroup_give_array(ID *id, MDeformVert **dvert_arr, int *dvert_tot) +bool ED_vgroup_give_array(ID *id, MDeformVert **dvert_arr, int *dvert_tot) { if (id) { switch (GS(id->name)) { @@ -324,7 +324,7 @@ int ED_vgroup_give_array(ID *id, MDeformVert **dvert_arr, int *dvert_tot) Mesh *me = (Mesh *)id; *dvert_arr = me->dvert; *dvert_tot = me->totvert; - return TRUE; + return true; } case ID_LT: { @@ -332,18 +332,18 @@ int ED_vgroup_give_array(ID *id, MDeformVert **dvert_arr, int *dvert_tot) lt = (lt->editlatt) ? lt->editlatt->latt : lt; *dvert_arr = lt->dvert; *dvert_tot = lt->pntsu * lt->pntsv * lt->pntsw; - return TRUE; + return true; } } } *dvert_arr = NULL; *dvert_tot = 0; - return FALSE; + return false; } /* matching index only */ -int ED_vgroup_copy_array(Object *ob, Object *ob_from) +bool ED_vgroup_copy_array(Object *ob, Object *ob_from) { MDeformVert **dvert_array_from, **dvf; MDeformVert **dvert_array, **dv; @@ -352,25 +352,25 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) int i; int defbase_tot_from = BLI_countlist(&ob_from->defbase); int defbase_tot = BLI_countlist(&ob->defbase); - short new_vgroup = FALSE; + bool new_vgroup = false; - ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from, FALSE); - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, FALSE); + ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from, false); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, false); if ((dvert_array == NULL) && (dvert_array_from != NULL) && ED_vgroup_data_create(ob->data)) { - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, FALSE); - new_vgroup = TRUE; + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, false); + new_vgroup = true; } if (ob == ob_from || dvert_tot == 0 || (dvert_tot != dvert_tot_from) || dvert_array_from == NULL || dvert_array == NULL) { if (dvert_array) MEM_freeN(dvert_array); if (dvert_array_from) MEM_freeN(dvert_array_from); - if (new_vgroup == TRUE) { + if (new_vgroup == true) { /* free the newly added vgroup since it wasn't compatible */ vgroup_delete_all(ob); } - return 0; + return false; } /* do the copy */ @@ -404,7 +404,7 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) MEM_freeN(dvert_array); MEM_freeN(dvert_array_from); - return 1; + return true; } /***********************Start weight transfer (WT)*********************************/ @@ -477,8 +477,8 @@ static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, /* Could be exposed externally by implementing it in header with the rest. * Simple refactoring will break something. * For now, naming is ed_ instead of ED_*/ -static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, - WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op) +static bool ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, + WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op) { bDeformGroup *dg_dst; Mesh *me_dst, *me_src; @@ -510,14 +510,14 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* Sanity check.*/ if (!me_src->dvert) { BKE_report(op->reports, RPT_ERROR, "Transfer failed (source mesh does not have any vertex groups)"); - return 0; + return false; } /* Create data in memory when nothing there.*/ if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data); /* Get vertex group arrays.*/ - ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); + ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, false); ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, use_vert_sel); /* Get indexes of vertex groups.*/ @@ -556,7 +556,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou if (dv_array_dst) MEM_freeN(dv_array_dst); dmesh_src->release(dmesh_src); BKE_report(op->reports, RPT_ERROR, "Transfer failed (indices are not matching)"); - return 0; + return false; } /* Loop through the vertices.*/ @@ -746,7 +746,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou if (dv_array_dst) MEM_freeN(dv_array_dst); dmesh_src->release(dmesh_src); - return 1; + return true; } /***********************End weight transfer (WT)***********************************/ @@ -1053,7 +1053,7 @@ static void vgroup_duplicate(Object *ob) icdg = (ob->actdef - 1); /* TODO, we might want to allow only copy selected verts here? - campbell */ - ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, FALSE); + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, false); if (dvert_array) { for (i = 0; i < dvert_tot; i++) { @@ -1277,12 +1277,12 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in int *dwIndices = MEM_callocN(sizeof(int) * totweight, "dwIndexTracker"); float distToStart; int bestIndex = 0; - char wasChange; + bool wasChange; char wasUp; int lastIndex = -1; float originalDistToBe = distToBe; do { - wasChange = FALSE; + wasChange = false; dm = dm_deform_recalc(scene, ob); dm->getVert(dm, index, &m); copy_v3_v3(oldPos, m.co); @@ -1392,12 +1392,12 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in } } if (bestIndex != -1) { - wasChange = TRUE; + wasChange = true; /* it is a good place to stop if it tries to move the opposite direction * (relative to the plane) of last time */ if (lastIndex != -1) { if (wasUp != upDown[bestIndex]) { - wasChange = FALSE; + wasChange = false; } } lastIndex = bestIndex; @@ -1414,7 +1414,7 @@ static void moveCloserToDistanceFromPlane(Scene *scene, Object *ob, Mesh *me, in dw->weight = 1; } if (oldw == dw->weight) { - wasChange = FALSE; + wasChange = false; } if (dm) { dm_deform_clear(dm, ob); dm = NULL; @@ -1512,7 +1512,7 @@ static void vgroup_levels(Object *ob, float offset, float gain) } } -static void vgroup_normalize_all(Object *ob, int lock_active) +static void vgroup_normalize_all(Object *ob, const bool lock_active) { MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; @@ -1530,11 +1530,11 @@ static void vgroup_normalize_all(Object *ob, int lock_active) const int defbase_tot = BLI_countlist(&ob->defbase); char *lock_flags = BKE_objdef_lock_flags_get(ob, defbase_tot); - if ((lock_active == TRUE) && + if ((lock_active == true) && (lock_flags != NULL) && (def_nr < defbase_tot)) { - lock_flags[def_nr] = TRUE; + lock_flags[def_nr] = true; } for (i = 0; i < dvert_tot; i++) { @@ -1604,7 +1604,7 @@ static void vgroup_lock_all(Object *ob, int action) } } -static void vgroup_invert(Object *ob, const short auto_assign, const short auto_remove) +static void vgroup_invert(Object *ob, const bool auto_assign, const bool auto_remove) { MDeformWeight *dw; MDeformVert *dv, **dvert_array = NULL; @@ -1796,20 +1796,20 @@ static int inv_cmp_mdef_vert_weights(const void *a1, const void *a2) /* Used for limiting the number of influencing bones per vertex when exporting * skinned meshes. if all_deform_weights is True, limit all deform modifiers * to max_weights regardless of type, otherwise, only limit the number of influencing bones per vertex*/ -static int vertex_group_limit_total(Object *ob, - const int max_weights, - const int all_deform_weights) +static bool vertex_group_limit_total(Object *ob, + const int max_weights, + const bool all_deform_weights) { MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; const int use_vert_sel = vertex_group_use_vert_sel(ob); - int is_change = FALSE; + bool is_change = false; ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); if (dvert_array) { int defbase_tot = BLI_countlist(&ob->defbase); - const char *vgroup_validmap = (all_deform_weights == FALSE) ? + const char *vgroup_validmap = (all_deform_weights == false) ? BKE_objdef_validmap_get(ob, defbase_tot) : NULL; int num_to_drop = 0; @@ -1830,7 +1830,7 @@ static int vertex_group_limit_total(Object *ob, qsort(dv->dw, dv->totweight, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights); dv->dw = MEM_reallocN(dv->dw, sizeof(MDeformWeight) * max_weights); dv->totweight = max_weights; - is_change = TRUE; + is_change = true; } } else { @@ -1866,7 +1866,7 @@ static int vertex_group_limit_total(Object *ob, /* Do we want to clean/normalize here? */ MEM_freeN(dv->dw); dv->dw = MEM_reallocN(dw_temp, sizeof(MDeformWeight) * dv->totweight); - is_change = TRUE; + is_change = true; } else { MEM_freeN(dw_temp); @@ -1884,7 +1884,7 @@ static int vertex_group_limit_total(Object *ob, return is_change; } -static void vgroup_clean(Object *ob, const float epsilon, int keep_single) +static void vgroup_clean(Object *ob, const float epsilon, const bool keep_single) { MDeformWeight *dw; MDeformVert *dv, **dvert_array = NULL; @@ -1911,7 +1911,7 @@ static void vgroup_clean(Object *ob, const float epsilon, int keep_single) if (dw) { if (dw->weight <= epsilon) { - if (keep_single == FALSE || dv->totweight > 1) { + if (keep_single == false || dv->totweight > 1) { defvert_remove_group(dv, dw); /* dw can be NULL */ } } @@ -1922,7 +1922,7 @@ static void vgroup_clean(Object *ob, const float epsilon, int keep_single) } } -static void vgroup_clean_all(Object *ob, const float epsilon, const int keep_single) +static void vgroup_clean_all(Object *ob, const float epsilon, const bool keep_single) { MDeformVert **dvert_array = NULL; int i, dvert_tot = 0; @@ -1965,8 +1965,8 @@ static void vgroup_clean_all(Object *ob, const float epsilon, const int keep_sin static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, const char sel, const char sel_mirr, const int *flip_map, const int flip_map_len, - const short mirror_weights, const short flip_vgroups, - const short all_vgroups, const int act_vgroup) + const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups, + const int act_vgroup) { BLI_assert(sel || sel_mirr); @@ -2020,7 +2020,8 @@ static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, /* TODO, vgroup locking */ /* TODO, face masking */ -void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_vgroups, const short all_vgroups) +void ED_vgroup_mirror(Object *ob, + const bool mirror_weights, const bool flip_vgroups, const bool all_vgroups) { #define VGROUP_MIRR_OP \ @@ -2033,11 +2034,11 @@ void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_v BMVert *eve, *eve_mirr; MDeformVert *dvert, *dvert_mirr; - short sel, sel_mirr; + char sel, sel_mirr; int *flip_map, flip_map_len; const int def_nr = ob->actdef - 1; - if ((mirror_weights == 0 && flip_vgroups == 0) || + if ((mirror_weights == false && flip_vgroups == false) || (BLI_findlink(&ob->defbase, def_nr) == NULL)) { return; @@ -2045,8 +2046,8 @@ void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_v if (flip_vgroups) { flip_map = all_vgroups ? - defgroup_flip_map(ob, &flip_map_len, FALSE) : - defgroup_flip_map_single(ob, &flip_map_len, FALSE, def_nr); + defgroup_flip_map(ob, &flip_map_len, false) : + defgroup_flip_map_single(ob, &flip_map_len, false, def_nr); BLI_assert(flip_map != NULL); @@ -2072,7 +2073,7 @@ void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_v goto cleanup; } - EDBM_verts_mirror_cache_begin(em, FALSE); + EDBM_verts_mirror_cache_begin(em, false); /* Go through the list of editverts and assign them */ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { @@ -2106,7 +2107,7 @@ void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_v } if (!use_vert_sel) { - sel = sel_mirr = TRUE; + sel = sel_mirr = true; } /* tag verts we have used */ @@ -2306,7 +2307,7 @@ static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg) /* only in editmode */ /* removes from active defgroup, if allverts==0 only selected vertices */ -static void vgroup_active_remove_verts(Object *ob, const int allverts, bDeformGroup *dg) +static void vgroup_active_remove_verts(Object *ob, const bool allverts, bDeformGroup *dg) { MDeformVert *dv; const int def_nr = BLI_findindex(&ob->defbase, dg); @@ -2378,7 +2379,7 @@ static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *dg) assert(dg_index > -1); /* Make sure that no verts are using this group */ - vgroup_active_remove_verts(ob, TRUE, dg); + vgroup_active_remove_verts(ob, true, dg); /* Make sure that any verts with higher indices are adjusted accordingly */ if (ob->type == OB_MESH) { @@ -2442,17 +2443,17 @@ static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *dg) } } -static int vgroup_object_in_edit_mode(Object *ob) +static bool vgroup_object_in_edit_mode(Object *ob) { if (ob->type == OB_MESH) return (BMEdit_FromObject(ob) != NULL); else if (ob->type == OB_LATTICE) return (((Lattice *)ob->data)->editlatt != NULL); - return 0; + return false; } -static int vgroup_object_in_wpaint_vert_select(Object *ob) +static bool vgroup_object_in_wpaint_vert_select(Object *ob) { if (ob->type == OB_MESH) { Mesh *me = ob->data; @@ -2461,7 +2462,7 @@ static int vgroup_object_in_wpaint_vert_select(Object *ob) (ME_EDIT_PAINT_SEL_MODE(me) == SCE_SELECT_VERTEX) ); } - return 0; + return false; } static void vgroup_delete(Object *ob) @@ -2739,7 +2740,7 @@ static int vertex_group_remove_from_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - vgroup_active_remove_verts(ob, FALSE, dg); + vgroup_active_remove_verts(ob, false, dg); } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -2914,7 +2915,7 @@ void OBJECT_OT_vertex_group_normalize(wmOperatorType *ot) static int vertex_group_normalize_all_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); - int lock_active = RNA_boolean_get(op->ptr, "lock_active"); + bool lock_active = RNA_boolean_get(op->ptr, "lock_active"); vgroup_normalize_all(ob, lock_active); @@ -2940,7 +2941,7 @@ void OBJECT_OT_vertex_group_normalize_all(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "lock_active", TRUE, "Lock Active", + RNA_def_boolean(ot->srna, "lock_active", true, "Lock Active", "Keep the values of the active group while normalizing others"); } @@ -3027,8 +3028,8 @@ void OBJECT_OT_vertex_group_lock(wmOperatorType *ot) static int vertex_group_invert_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); - int auto_assign = RNA_boolean_get(op->ptr, "auto_assign"); - int auto_remove = RNA_boolean_get(op->ptr, "auto_remove"); + bool auto_assign = RNA_boolean_get(op->ptr, "auto_assign"); + bool auto_remove = RNA_boolean_get(op->ptr, "auto_remove"); vgroup_invert(ob, auto_assign, auto_remove); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); @@ -3052,9 +3053,9 @@ void OBJECT_OT_vertex_group_invert(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "auto_assign", TRUE, "Add Weights", + RNA_def_boolean(ot->srna, "auto_assign", true, "Add Weights", "Add verts from groups that have zero weight before inverting"); - RNA_def_boolean(ot->srna, "auto_remove", TRUE, "Remove Weights", + RNA_def_boolean(ot->srna, "auto_remove", true, "Remove Weights", "Remove verts from groups that have zero weight after inverting"); } @@ -3080,23 +3081,23 @@ static int vertex_group_blend_poll(bContext *C) ID *data = (ob) ? ob->data : NULL; if (!(ob && !ob->id.lib && data && !data->lib)) - return FALSE; + return false; if (vgroup_object_in_edit_mode(ob)) { - return TRUE; + return true; } else if ((ob->type == OB_MESH) && (ob->mode & OB_MODE_WEIGHT_PAINT)) { if (ME_EDIT_PAINT_SEL_MODE(((Mesh *)data)) == SCE_SELECT_VERTEX) { - return TRUE; + return true; } else { CTX_wm_operator_poll_msg_set(C, "Vertex select needs to be enabled in weight paint mode"); - return FALSE; + return false; } } else { - return FALSE; + return false; } } @@ -3128,8 +3129,8 @@ static int vertex_group_clean_exec(bContext *C, wmOperator *op) Object *ob = ED_object_context(C); float limit = RNA_float_get(op->ptr, "limit"); - int all_groups = RNA_boolean_get(op->ptr, "all_groups"); - int keep_single = RNA_boolean_get(op->ptr, "keep_single"); + bool all_groups = RNA_boolean_get(op->ptr, "all_groups"); + bool keep_single = RNA_boolean_get(op->ptr, "keep_single"); if (all_groups) vgroup_clean_all(ob, limit, keep_single); else vgroup_clean(ob, limit, keep_single); @@ -3156,8 +3157,8 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; RNA_def_float(ot->srna, "limit", 0.0f, 0.0f, 1.0, "Limit", "Remove weights under this limit", 0.0f, 0.99f); - RNA_def_boolean(ot->srna, "all_groups", FALSE, "All Groups", "Clean all vertex groups"); - RNA_def_boolean(ot->srna, "keep_single", FALSE, "Keep Single", + RNA_def_boolean(ot->srna, "all_groups", false, "All Groups", "Clean all vertex groups"); + RNA_def_boolean(ot->srna, "keep_single", false, "Keep Single", "Keep verts assigned to at least one group when cleaning"); } @@ -3166,7 +3167,7 @@ static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) Object *ob = ED_object_context(C); const int limit = RNA_int_get(op->ptr, "limit"); - const int all_deform_weights = RNA_boolean_get(op->ptr, "all_deform_weights"); + const bool all_deform_weights = RNA_boolean_get(op->ptr, "all_deform_weights"); if (vertex_group_limit_total(ob, limit, all_deform_weights)) { @@ -3200,7 +3201,7 @@ void OBJECT_OT_vertex_group_limit_total(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; RNA_def_int(ot->srna, "limit", 4, 1, 32, "Limit", "Maximum number of deform weights", 1, 32); - RNA_def_boolean(ot->srna, "all_deform_weights", FALSE, "All Deform Weights", "Cull all deform weights, not just bones"); + RNA_def_boolean(ot->srna, "all_deform_weights", false, "All Deform Weights", "Cull all deform weights, not just bones"); } static int vertex_group_mirror_exec(bContext *C, wmOperator *op) @@ -3235,9 +3236,9 @@ void OBJECT_OT_vertex_group_mirror(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_boolean(ot->srna, "mirror_weights", TRUE, "Mirror Weights", "Mirror weights"); - RNA_def_boolean(ot->srna, "flip_group_names", TRUE, "Flip Group Names", "Flip vertex group names"); - RNA_def_boolean(ot->srna, "all_groups", FALSE, "All Groups", "Mirror all vertex groups weights"); + RNA_def_boolean(ot->srna, "mirror_weights", true, "Mirror Weights", "Mirror weights"); + RNA_def_boolean(ot->srna, "flip_group_names", true, "Flip Group Names", "Flip vertex group names"); + RNA_def_boolean(ot->srna, "all_groups", false, "All Groups", "Mirror all vertex groups weights"); } diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 3469604b3dd..b6ee9254396 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -540,6 +540,13 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, if (type == GL_FLOAT) { /* need to set internal format to higher range float */ + + /* NOTE: this could fail on some drivers, like mesa, + * but currently this code is only used by color + * management stuff which already checks on whether + * it's possible to use GL_RGBA16F_ARB + */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F_ARB, tex_w, tex_h, 0, format, GL_FLOAT, NULL); } else { @@ -1028,7 +1035,9 @@ void bglFlush(void) /* **** Color management helper functions for GLSL display/transform ***** */ /* Draw given image buffer on a screen using GLSL for display transform */ -void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter) +void glaDrawImBuf_glsl(ImBuf *ibuf, float x, float y, int zoomfilter, + ColorManagedViewSettings *view_settings, + ColorManagedDisplaySettings *display_settings) { bool force_fallback = false; bool need_fallback = true; @@ -1080,10 +1089,19 @@ void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int if (force_fallback == false) { int ok; - if (ibuf->rect_float) - ok = IMB_colormanagement_setup_glsl_draw_ctx(C, TRUE); - else - ok = IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, ibuf->rect_colorspace, FALSE); + if (ibuf->rect_float) { + if (ibuf->float_colorspace) { + ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, + ibuf->float_colorspace, TRUE); + } + else { + ok = IMB_colormanagement_setup_glsl_draw(view_settings, display_settings, TRUE); + } + } + else { + ok = IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, + ibuf->rect_colorspace, FALSE); + } if (ok) { glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); @@ -1121,7 +1139,7 @@ void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int unsigned char *display_buffer; void *cache_handle; - display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); + display_buffer = IMB_display_buffer_acquire(ibuf, view_settings, display_settings, &cache_handle); if (display_buffer) glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, @@ -1131,6 +1149,16 @@ void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int } } +void glaDrawImBuf_glsl_ctx(const bContext *C, ImBuf *ibuf, float x, float y, int zoomfilter) +{ + ColorManagedViewSettings *view_settings; + ColorManagedDisplaySettings *display_settings; + + IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings); + + glaDrawImBuf_glsl(ibuf, x, y, zoomfilter, view_settings, display_settings); +} + /* Transform buffer from role to scene linear space using GLSL OCIO conversion * * See IMB_colormanagement_setup_transform_from_role_glsl description for diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 40a18734948..796bb99ebaf 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -38,9 +38,11 @@ #include "BKE_context.h" #include "BKE_paint.h" #include "BKE_main.h" +#include "BKE_image.h" #include "ED_sculpt.h" #include "ED_screen.h" +#include "ED_image.h" #include "UI_resources.h" #include "WM_api.h" @@ -447,20 +449,26 @@ static void BRUSH_OT_uv_sculpt_tool_set(wmOperatorType *ot) /***** Stencil Control *****/ -enum { +typedef enum { STENCIL_TRANSLATE, STENCIL_SCALE, STENCIL_ROTATE } StencilControlMode; +typedef enum { +STENCIL_CONSTRAINT_X = 1, +STENCIL_CONSTRAINT_Y = 2 +} StencilConstraint; + typedef struct { - int init_mouse[2]; - int init_spos[2]; - int init_sdim[2]; + float init_mouse[2]; + float init_spos[2]; + float init_sdim[2]; float init_rot; float init_angle; float lenorig; - int mode; + StencilControlMode mode; + StencilConstraint constrain_mode; Brush *br; } StencilControlData; @@ -468,15 +476,16 @@ static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *ev { Paint *paint = paint_get_active_from_context(C); Brush *br = paint_brush(paint); - int mdiff[2]; + float mdiff[2]; + float mvalf[2] = {event->mval[0], event->mval[1]}; StencilControlData *scd = MEM_mallocN(sizeof(StencilControlData), "stencil_control"); - copy_v2_v2_int(scd->init_mouse, event->mval); - copy_v2_v2_int(scd->init_sdim, br->stencil_dimension); - copy_v2_v2_int(scd->init_spos, br->stencil_pos); - sub_v2_v2v2_int(mdiff, event->mval, br->stencil_pos); - scd->lenorig = sqrtf(mdiff[0] * mdiff[0] + mdiff[1] * mdiff[1]); + copy_v2_v2(scd->init_mouse, mvalf); + copy_v2_v2(scd->init_sdim, br->stencil_dimension); + copy_v2_v2(scd->init_spos, br->stencil_pos); + sub_v2_v2v2(mdiff, mvalf, br->stencil_pos); + scd->lenorig = len_v2(mdiff); scd->br = br; scd->init_rot = br->mtex.rot; scd->init_angle = atan2(mdiff[1], mdiff[0]); @@ -494,8 +503,8 @@ static int stencil_control_cancel(bContext *UNUSED(C), wmOperator *op) StencilControlData *scd = op->customdata; Brush *br = scd->br; - copy_v2_v2_int(br->stencil_dimension, scd->init_sdim); - copy_v2_v2_int(br->stencil_pos, scd->init_spos); + copy_v2_v2(br->stencil_dimension, scd->init_sdim); + copy_v2_v2(br->stencil_pos, scd->init_spos); br->mtex.rot = scd->init_rot; MEM_freeN(op->customdata); return OPERATOR_CANCELLED; @@ -508,28 +517,32 @@ static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *eve switch (event->type) { case MOUSEMOVE: { - int mdiff[2]; + float mdiff[2]; + float mvalf[2] = {event->mval[0], event->mval[1]}; switch (scd->mode) { case STENCIL_TRANSLATE: - sub_v2_v2v2_int(mdiff, event->mval, scd->init_mouse); - add_v2_v2v2_int(scd->br->stencil_pos, scd->init_spos, + sub_v2_v2v2(mdiff, mvalf, scd->init_mouse); + add_v2_v2v2(scd->br->stencil_pos, scd->init_spos, mdiff); break; case STENCIL_SCALE: { float len, factor; - sub_v2_v2v2_int(mdiff, event->mval, scd->br->stencil_pos); - len = sqrtf(mdiff[0] * mdiff[0] + mdiff[1] * mdiff[1]); + sub_v2_v2v2(mdiff, mvalf, scd->br->stencil_pos); + len = len_v2(mdiff); factor = len / scd->lenorig; - mdiff[0] = factor * scd->init_sdim[0]; - mdiff[1] = factor * scd->init_sdim[1]; - copy_v2_v2_int(scd->br->stencil_dimension, mdiff); + copy_v2_v2(mdiff, scd->init_sdim); + if (scd->constrain_mode != STENCIL_CONSTRAINT_Y) + mdiff[0] = factor * scd->init_sdim[0]; + if (scd->constrain_mode != STENCIL_CONSTRAINT_X) + mdiff[1] = factor * scd->init_sdim[1]; + copy_v2_v2(scd->br->stencil_dimension, mdiff); break; } case STENCIL_ROTATE: { float angle; - sub_v2_v2v2_int(mdiff, event->mval, scd->br->stencil_pos); + sub_v2_v2v2(mdiff, mvalf, scd->br->stencil_pos); angle = atan2(mdiff[1], mdiff[0]); angle = scd->init_rot + angle - scd->init_angle; if (angle < 0.0f) @@ -555,6 +568,23 @@ static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *eve WM_event_add_notifier(C, NC_WINDOW, NULL); return OPERATOR_CANCELLED; } + case XKEY: + if (event->val == KM_PRESS) { + + if (scd->constrain_mode == STENCIL_CONSTRAINT_X) + scd->constrain_mode = 0; + else + scd->constrain_mode = STENCIL_CONSTRAINT_X; + } + break; + case YKEY: + if (event->val == KM_PRESS) { + if (scd->constrain_mode == STENCIL_CONSTRAINT_Y) + scd->constrain_mode = 0; + else + scd->constrain_mode = STENCIL_CONSTRAINT_Y; + } + break; default: break; } @@ -597,6 +627,48 @@ static void BRUSH_OT_stencil_control(wmOperatorType *ot) RNA_def_enum(ot->srna, "mode", stencil_control_items, 0, "Tool", ""); } + +static int stencil_fit_image_aspect_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Paint *paint = paint_get_active_from_context(C); + Brush *br = paint_brush(paint); + Tex *tex = (br)? br->mtex.tex : NULL; + + if (tex && tex->type == TEX_IMAGE && tex->ima) { + float aspx, aspy; + Image *ima = tex->ima; + float orig_area, stencil_area, factor; + ED_image_get_uv_aspect(ima, NULL, &aspx, &aspy); + + orig_area = aspx*aspy; + stencil_area = br->stencil_dimension[0]*br->stencil_dimension[1]; + + factor = sqrt(stencil_area/orig_area); + + br->stencil_dimension[0] = factor*aspx; + br->stencil_dimension[1] = factor*aspy; + } + + return OPERATOR_FINISHED; +} + + +static void BRUSH_OT_stencil_fit_image_aspect(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Image Aspect"; + ot->description = "Adjust the stencil size to fit image aspect ratio"; + ot->idname = "BRUSH_OT_stencil_fit_image_aspect"; + + /* api callbacks */ + ot->exec = stencil_fit_image_aspect_exec; + ot->poll = stencil_control_poll; + + /* flags */ + ot->flag = 0; +} + + static void ed_keymap_stencil(wmKeyMap *keymap) { wmKeyMapItem *kmi; @@ -620,6 +692,7 @@ void ED_operatortypes_paint(void) WM_operatortype_append(BRUSH_OT_curve_preset); WM_operatortype_append(BRUSH_OT_reset); WM_operatortype_append(BRUSH_OT_stencil_control); + WM_operatortype_append(BRUSH_OT_stencil_fit_image_aspect); /* note, particle uses a different system, can be added with existing operators in wm.py */ WM_operatortype_append(PAINT_OT_brush_select); diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index a51315d9a16..1c4ea8b5546 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -2734,7 +2734,7 @@ void CLIP_OT_frame_jump(wmOperatorType *ot) /* api callbacks */ ot->exec = frame_jump_exec; - ot->poll = ED_space_clip_tracking_poll; + ot->poll = ED_space_clip_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 74f776549e9..a6379e6465f 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -225,7 +225,12 @@ static void console_line_verify_length(ConsoleLine *ci, int len) { /* resize the buffer if needed */ if (len >= ci->len_alloc) { - int new_len = len * 2; /* new length */ + /* new length */ +#ifndef NDEBUG + int new_len = len + 1; +#else + int new_len = (len + 1) * 2; +#endif char *new_line = MEM_callocN(new_len, "console line"); memcpy(new_line, ci->line, ci->len); MEM_freeN(ci->line); @@ -582,7 +587,7 @@ static int console_delete_exec(bContext *C, wmOperator *op) stride = ci->cursor - pos; if (stride) { ci->cursor -= stride; /* same as above */ - memmove(ci->line + ci->cursor, ci->line + ci->cursor + stride, (ci->len - ci->cursor) + 1); + memmove(ci->line + ci->cursor, ci->line + ci->cursor + stride, (ci->len - (ci->cursor + stride)) + 1); ci->len -= stride; BLI_assert(ci->len >= 0); done = TRUE; diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index d7206c9b111..cd3de834e78 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2948,8 +2948,6 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); if (ibuf) { float x, y; - unsigned char *display_buffer; - void *cache_handle; glMatrixMode(GL_PROJECTION); glPushMatrix(); @@ -2967,14 +2965,16 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) x = (ar->winx - snode->zoom * ibuf->x) / 2 + snode->xof; y = (ar->winy - snode->zoom * ibuf->y) / 2 + snode->yof; - - display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); + if (ibuf->rect || ibuf->rect_float) { + unsigned char *display_buffer = NULL; + void *cache_handle = NULL; - if (display_buffer) { if (snode->flag & (SNODE_SHOW_R | SNODE_SHOW_G | SNODE_SHOW_B)) { int ofs; + display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); + #ifdef __BIG_ENDIAN__ if (snode->flag & SNODE_SHOW_R) ofs = 2; else if (snode->flag & SNODE_SHOW_G) ofs = 1; @@ -2994,6 +2994,8 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) glPixelZoom(1.0f, 1.0f); } else if (snode->flag & SNODE_SHOW_ALPHA) { + display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); + glPixelZoom(snode->zoom, snode->zoom); /* swap bytes, so alpha is most significant one, then just draw it as luminance int */ #ifdef __BIG_ENDIAN__ @@ -3011,7 +3013,7 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glPixelZoom(snode->zoom, snode->zoom); - glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer); + glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST); glPixelZoom(1.0f, 1.0f); glDisable(GL_BLEND); @@ -3019,13 +3021,14 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) else { glPixelZoom(snode->zoom, snode->zoom); - glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer); + glaDrawImBuf_glsl_ctx(C, ibuf, x, y, GL_NEAREST); glPixelZoom(1.0f, 1.0f); } - } - IMB_display_buffer_release(cache_handle); + if (cache_handle) + IMB_display_buffer_release(cache_handle); + } /** @note draw selected info on backdrop */ if (snode->edittree) { diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 141af5d5ba4..3a7610cbf2a 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -920,9 +920,11 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq float col[3]; GLuint texid; GLuint last_texid; - unsigned char *display_buffer; + void *display_buffer; void *cache_handle = NULL; const int is_imbuf = ED_space_sequencer_check_show_imbuf(sseq); + int format, type; + bool glsl_used = false; if (G.is_rendering == FALSE && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) { /* stop all running jobs, except screen one. currently previews frustrate Render @@ -1040,9 +1042,46 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq } display_buffer = (unsigned char *)ibuf->rect; + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; } else { - display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); + if (ibuf->rect_float) { + display_buffer = ibuf->rect_float; + + if (ibuf->channels == 4) { + format = GL_RGBA; + } + else if (ibuf->channels == 3) { + format = GL_RGB; + } + else { + BLI_assert(!"Incompatible number of channels for float buffer in sequencer"); + format = GL_RGBA; + display_buffer = NULL; + } + + type = GL_FLOAT; + + if (ibuf->float_colorspace) { + glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, ibuf->float_colorspace, TRUE); + } + else { + glsl_used = IMB_colormanagement_setup_glsl_draw_ctx(C, TRUE); + } + } + else if (ibuf->rect) { + display_buffer = ibuf->rect; + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + + glsl_used = IMB_colormanagement_setup_glsl_draw_from_space_ctx(C, ibuf->rect_colorspace, FALSE); + } + else { + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + display_buffer = NULL; + } } /* setting up the view - actual drawing starts here */ @@ -1068,7 +1107,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, format, type, display_buffer); glBegin(GL_QUADS); @@ -1105,6 +1144,9 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glDisable(GL_BLEND); glDeleteTextures(1, &texid); + if (glsl_used) + IMB_colormanagement_finish_glsl_draw(); + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { float x1 = v2d->tot.xmin; diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index d0437c77af7..983b479f550 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1528,7 +1528,7 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, /* smart function to sample a rect spiralling outside, nice for backbuf selection */ unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int size, unsigned int min, unsigned int max, float *r_dist, short strict, - void *handle, unsigned int (*indextest)(void *handle, unsigned int index)) + void *handle, bool (*indextest)(void *handle, unsigned int index)) { struct ImBuf *buf; unsigned int *bufmin, *bufmax, *tbuf; @@ -1536,7 +1536,7 @@ unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int int a, b, rc, nr, amount, dirvec[4][2]; int distance = 0; unsigned int index = 0; - short indexok = 0; + bool indexok = false; amount = (size - 1) / 2; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index be296025624..bf4baf9ea22 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -1407,12 +1407,16 @@ int calculateTransformCenter(bContext *C, int centerMode, float cent3d[3], int c t->state = TRANS_RUNNING; - t->options = CTX_NONE; + /* avoid calculating PET */ + t->options = CTX_NONE | CTX_NO_PET; t->mode = TFM_DUMMY; initTransInfo(C, t, NULL, NULL); // internal data, mouse, vectors + /* avoid doing connectivity lookups (when V3D_LOCAL is set) */ + t->around = V3D_CENTER; + createTransData(C, t); // make TransData structs from selection t->around = centerMode; // override userdefined mode diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 661d7055036..2098c4a1e27 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -5182,7 +5182,7 @@ void special_aftertrans_update(bContext *C, TransInfo *t) * during cleanup - psy-fi */ freeEdgeSlideTempFaces(sld); } - EDBM_automerge(t->scene, t->obedit, TRUE); + EDBM_automerge(t->scene, t->obedit, true); } else { if (t->mode == TFM_EDGE_SLIDE) { diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index ba8b26c9083..14478db3846 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -1427,9 +1427,7 @@ static int reset_exec(bContext *C, wmOperator *UNUSED(op)) return OPERATOR_CANCELLED; } - if (!ED_mesh_uv_loop_reset(C, me)) { - return OPERATOR_CANCELLED; - } + ED_mesh_uv_loop_reset(C, me); DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h index 58b55b0f137..314daed00dd 100644 --- a/source/blender/imbuf/IMB_colormanagement.h +++ b/source/blender/imbuf/IMB_colormanagement.h @@ -95,6 +95,10 @@ struct ImBuf *IMB_colormanagement_imbuf_for_write(struct ImBuf *ibuf, int save_a /* ** Public display buffers interfaces ** */ +void IMB_colormanagement_display_settings_from_ctx(const struct bContext *C, + struct ColorManagedViewSettings **view_settings_r, + struct ColorManagedDisplaySettings **display_settings_r); + unsigned char *IMB_display_buffer_acquire(struct ImBuf *ibuf, const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings, void **cache_handle); unsigned char *IMB_display_buffer_acquire_ctx(const struct bContext *C, struct ImBuf *ibuf, void **cache_handle); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index a74f28e79c9..b8de1cf75d1 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -662,8 +662,9 @@ void colormanage_cache_free(ImBuf *ibuf) } } -static void display_transform_get_from_ctx(const bContext *C, ColorManagedViewSettings **view_settings_r, - ColorManagedDisplaySettings **display_settings_r) +void IMB_colormanagement_display_settings_from_ctx(const bContext *C, + ColorManagedViewSettings **view_settings_r, + ColorManagedDisplaySettings **display_settings_r) { Scene *scene = CTX_data_scene(C); SpaceImage *sima = CTX_wm_space_image(C); @@ -1963,7 +1964,7 @@ unsigned char *IMB_display_buffer_acquire_ctx(const bContext *C, ImBuf *ibuf, vo ColorManagedViewSettings *view_settings; ColorManagedDisplaySettings *display_settings; - display_transform_get_from_ctx(C, &view_settings, &display_settings); + IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings); return IMB_display_buffer_acquire(ibuf, view_settings, display_settings, cache_handle); } @@ -2820,7 +2821,7 @@ int IMB_colormanagement_setup_glsl_draw_from_space_ctx(const struct bContext *C, ColorManagedViewSettings *view_settings; ColorManagedDisplaySettings *display_settings; - display_transform_get_from_ctx(C, &view_settings, &display_settings); + IMB_colormanagement_display_settings_from_ctx(C, &view_settings, &display_settings); return IMB_colormanagement_setup_glsl_draw_from_space(view_settings, display_settings, from_colorspace, predivide); } diff --git a/source/blender/imbuf/intern/thumbs.c b/source/blender/imbuf/intern/thumbs.c index 51c6c2fc2d9..44358d8147e 100644 --- a/source/blender/imbuf/intern/thumbs.c +++ b/source/blender/imbuf/intern/thumbs.c @@ -285,8 +285,8 @@ ImBuf *IMB_thumb_create(const char *path, ThumbSize size, ThumbSource source, Im /* exception, skip images over 100mb */ if (source == THB_SOURCE_IMAGE) { - const size_t size = BLI_file_size(path); - if (size != -1 && size > THUMB_SIZE_MAX) { + const size_t file_size = BLI_file_size(path); + if (file_size != -1 && file_size > THUMB_SIZE_MAX) { // printf("file too big: %d, skipping %s\n", (int)size, path); return NULL; } diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 11dd68bb11b..97ff24d3366 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -106,8 +106,8 @@ typedef struct Brush { float add_col[3]; float sub_col[3]; - int stencil_pos[2]; - int stencil_dimension[2]; + float stencil_pos[2]; + float stencil_dimension[2]; } Brush; /* Brush.flag */ diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 22259d71a2f..7d817f3dbe0 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -1112,10 +1112,11 @@ __attribute__ ((format(printf, 1, 2))) #endif ; -/* Equals test (skips pointers and collections) */ +/* Equals test (skips pointers and collections) + * is_strict false assumes uninitialized properties are equal */ -int RNA_property_equals(struct PointerRNA *a, struct PointerRNA *b, struct PropertyRNA *prop); -int RNA_struct_equals(struct PointerRNA *a, struct PointerRNA *b); +bool RNA_property_equals(struct PointerRNA *a, struct PointerRNA *b, struct PropertyRNA *prop, bool is_strict); +bool RNA_struct_equals(struct PointerRNA *a, struct PointerRNA *b, bool is_strict); #ifdef __cplusplus } diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index 00ee1b49da2..3d2f29b94af 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -6179,14 +6179,21 @@ void _RNA_warning(const char *format, ...) #endif } -int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop) +bool RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop, bool is_strict) { + int len, fromlen; + + /* if not strict, uninitialized properties are assumed to match */ + if (!is_strict) + if (!(RNA_property_is_set(a, prop) && RNA_property_is_set(b, prop))) + return true; + /* get the length of the array to work with */ - int len = RNA_property_array_length(a, prop); - int fromlen = RNA_property_array_length(b, prop); + len = RNA_property_array_length(a, prop); + fromlen = RNA_property_array_length(b, prop); if (len != fromlen) - return 0; + return false; /* get and set the default values as appropriate for the various types */ switch (RNA_property_type(prop)) { @@ -6195,7 +6202,7 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop) if (len) { int fixed_a[16], fixed_b[16]; int *array_a, *array_b; - int equals; + bool equals; array_a = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals") : fixed_a; array_b = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals") : fixed_b; @@ -6221,7 +6228,7 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop) if (len) { int fixed_a[16], fixed_b[16]; int *array_a, *array_b; - int equals; + bool equals; array_a = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_a; array_b = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_b; @@ -6247,7 +6254,7 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop) if (len) { float fixed_a[16], fixed_b[16]; float *array_a, *array_b; - int equals; + bool equals; array_a = (len > 16) ? MEM_callocN(sizeof(float) * len, "RNA equals") : fixed_a; array_b = (len > 16) ? MEM_callocN(sizeof(float) * len, "RNA equals") : fixed_b; @@ -6280,7 +6287,7 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop) int len_a, len_b; char *value_a = RNA_property_string_get_alloc(a, prop, fixed_a, sizeof(fixed_a), &len_a); char *value_b = RNA_property_string_get_alloc(b, prop, fixed_b, sizeof(fixed_b), &len_b); - int equals = strcmp(value_a, value_b) == 0; + bool equals = strcmp(value_a, value_b) == 0; if (value_a != fixed_a) MEM_freeN(value_a); if (value_b != fixed_b) MEM_freeN(value_b); @@ -6292,22 +6299,22 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop) break; } - return 1; + return true; } -int RNA_struct_equals(PointerRNA *a, PointerRNA *b) +bool RNA_struct_equals(PointerRNA *a, PointerRNA *b, bool is_strict) { CollectionPropertyIterator iter; // CollectionPropertyRNA *citerprop; /* UNUSED */ PropertyRNA *iterprop; - int equals = 1; + bool equals = true; if (a == NULL && b == NULL) - return 1; + return true; else if (a == NULL || b == NULL) - return 0; + return false; else if (a->type != b->type) - return 0; + return false; iterprop = RNA_struct_iterator_property(a->type); // citerprop = (CollectionPropertyRNA *)rna_ensure_property(iterprop); /* UNUSED */ @@ -6316,8 +6323,8 @@ int RNA_struct_equals(PointerRNA *a, PointerRNA *b) for (; iter.valid; RNA_property_collection_next(&iter)) { PropertyRNA *prop = iter.ptr.data; - if (!RNA_property_equals(a, b, prop)) { - equals = 0; + if (!RNA_property_equals(a, b, prop, is_strict)) { + equals = false; break; } } diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 8946274fc38..0c5b257733a 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -793,6 +793,18 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Autosmooth", "Amount of smoothing to automatically apply to each stroke"); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "stencil_pos", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "stencil_pos"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Stencil Position", "Position of stencil in viewport"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + + prop = RNA_def_property(srna, "stencil_dimension", PROP_FLOAT, PROP_XYZ); + RNA_def_property_float_sdna(prop, NULL, "stencil_dimension"); + RNA_def_property_array(prop, 2); + RNA_def_property_ui_text(prop, "Stencil Dimensions", "Dimensions of stencil in viewport"); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + /* flag */ prop = RNA_def_property(srna, "use_airbrush", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_AIRBRUSH); diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index d504585f738..ba45e10ae08 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -313,7 +313,7 @@ Mesh *rna_Main_meshes_new_from_object( copycu->editnurb = tmpcu->editnurb; /* get updated display list, and convert to a mesh */ - BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, FALSE); + BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, FALSE, render); copycu->editfont = NULL; copycu->editnurb = NULL; diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 16f63e31353..7ccf11af829 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -6872,6 +6872,11 @@ static void rna_def_nodetree(BlenderRNA *brna) RNA_def_struct_refine_func(srna, "rna_NodeTree_refine"); RNA_def_struct_register_funcs(srna, "rna_NodeTree_register", "rna_NodeTree_unregister", NULL); + prop = RNA_def_property(srna, "view_center", PROP_FLOAT, PROP_XYZ); + RNA_def_property_array(prop, 2); + RNA_def_property_float_sdna(prop, NULL, "view_center"); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + /* AnimData */ rna_def_animdata_common(srna); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index e036bb1c999..7a69f3c6b7c 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -3357,7 +3357,8 @@ static void rna_def_space_node(BlenderRNA *brna) RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); /* the mx/my "cursor" in the node editor is used only by operators to store the mouse position */ - prop = RNA_def_property(srna, "cursor_location", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "cursor_location", PROP_FLOAT, PROP_XYZ); + RNA_def_property_array(prop, 2); RNA_def_property_float_sdna(prop, NULL, "cursor"); RNA_def_property_ui_text(prop, "Cursor Location", "Location for adding new nodes"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL); diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c index 50ef122fe60..c9b18009b71 100644 --- a/source/blender/nodes/shader/node_shader_tree.c +++ b/source/blender/nodes/shader/node_shader_tree.c @@ -272,10 +272,12 @@ void ntreeShaderEndExecTree_internal(bNodeTreeExec *exec) void ntreeShaderEndExecTree(bNodeTreeExec *exec) { if (exec) { + /* exec may get freed, so assign ntree */ + bNodeTree *ntree = exec->nodetree; ntreeShaderEndExecTree_internal(exec); /* XXX clear nodetree backpointer to exec data, same problem as noted in ntreeBeginExecTree */ - exec->nodetree->execdata = NULL; + ntree->execdata = NULL; } } diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index a591b41db98..6aaa58f0ed4 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -423,6 +423,15 @@ static PyObject *bpy_bmedge_is_contiguous_get(BPy_BMEdge *self) return PyBool_FromLong(BM_edge_is_contiguous(self->e)); } +PyDoc_STRVAR(bpy_bmedge_is_convex_doc, +"True when this edge joins 2 convex faces, depends on a valid face normal (read-only).\n\n:type: boolean" +); +static PyObject *bpy_bmedge_is_convex_get(BPy_BMEdge *self) +{ + BPY_BM_CHECK_OBJ(self); + return PyBool_FromLong(BM_edge_is_convex(self->e)); +} + PyDoc_STRVAR(bpy_bmedge_is_wire_doc, "True when this edge is not connected to any faces (read-only).\n\n:type: boolean" ); @@ -652,10 +661,10 @@ static PyObject *bpy_bmloop_link_loop_radial_prev_get(BPy_BMLoop *self) return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_prev); } -PyDoc_STRVAR(bpy_bm_is_convex_doc, -"True when this loop is at the convex corner of a face, depends on a valid face normal (read-only).\n\n:type: :class:`BMLoop`" +PyDoc_STRVAR(bpy_bmloop_is_convex_doc, +"True when this loop is at the convex corner of a face, depends on a valid face normal (read-only).\n\n:type: boolean" ); -static PyObject *bpy_bm_is_convex_get(BPy_BMLoop *self) +static PyObject *bpy_bmloop_is_convex_get(BPy_BMLoop *self) { BPY_BM_CHECK_OBJ(self); return PyBool_FromLong(BM_loop_is_convex(self->l)); @@ -777,6 +786,7 @@ static PyGetSetDef bpy_bmedge_getseters[] = { /* readonly checks */ {(char *)"is_manifold", (getter)bpy_bmedge_is_manifold_get, (setter)NULL, (char *)bpy_bmedge_is_manifold_doc, NULL}, {(char *)"is_contiguous", (getter)bpy_bmedge_is_contiguous_get, (setter)NULL, (char *)bpy_bmedge_is_contiguous_doc, NULL}, + {(char *)"is_convex", (getter)bpy_bmedge_is_convex_get, (setter)NULL, (char *)bpy_bmedge_is_convex_doc, NULL}, {(char *)"is_wire", (getter)bpy_bmedge_is_wire_get, (setter)NULL, (char *)bpy_bmedge_is_wire_doc, NULL}, {(char *)"is_boundary", (getter)bpy_bmedge_is_boundary_get, (setter)NULL, (char *)bpy_bmedge_is_boundary_doc, NULL}, {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL}, @@ -832,8 +842,8 @@ static PyGetSetDef bpy_bmloop_getseters[] = { {(char *)"link_loop_radial_prev", (getter)bpy_bmloop_link_loop_radial_prev_get, (setter)NULL, (char *)bpy_bmloop_link_loop_radial_prev_doc, NULL}, /* readonly checks */ - {(char *)"is_convex", (getter)bpy_bm_is_convex_get, (setter)NULL, (char *)bpy_bm_is_convex_doc, NULL}, - {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL}, + {(char *)"is_convex", (getter)bpy_bmloop_is_convex_get, (setter)NULL, (char *)bpy_bmloop_is_convex_doc, NULL}, + {(char *)"is_valid", (getter)bpy_bm_is_valid_get, (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL}, {NULL, NULL, NULL, NULL, NULL} /* Sentinel */ }; @@ -1489,6 +1499,18 @@ static PyObject *bpy_bmedge_calc_face_angle(BPy_BMEdge *self) return PyFloat_FromDouble(BM_edge_calc_face_angle(self->e)); } +PyDoc_STRVAR(bpy_bmedge_calc_face_angle_signed_doc, +".. method:: calc_face_angle_signed()\n" +"\n" +" :return: The angle between 2 connected faces in radians (negative for concave join).\n" +" :rtype: float\n" +); +static PyObject *bpy_bmedge_calc_face_angle_signed(BPy_BMEdge *self) +{ + BPY_BM_CHECK_OBJ(self); + return PyFloat_FromDouble(BM_edge_calc_face_angle_signed(self->e)); +} + PyDoc_STRVAR(bpy_bmedge_calc_tangent_doc, ".. method:: calc_tangent(loop)\n" "\n" @@ -2531,6 +2553,7 @@ static struct PyMethodDef bpy_bmedge_methods[] = { {"calc_length", (PyCFunction)bpy_bmedge_calc_length, METH_NOARGS, bpy_bmedge_calc_length_doc}, {"calc_face_angle", (PyCFunction)bpy_bmedge_calc_face_angle, METH_NOARGS, bpy_bmedge_calc_face_angle_doc}, + {"calc_face_angle_signed", (PyCFunction)bpy_bmedge_calc_face_angle_signed, METH_NOARGS, bpy_bmedge_calc_face_angle_signed_doc}, {"calc_tangent", (PyCFunction)bpy_bmedge_calc_tangent, METH_VARARGS, bpy_bmedge_calc_tangent_doc}, {"normal_update", (PyCFunction)bpy_bmedge_normal_update, METH_NOARGS, bpy_bmedge_normal_update_doc}, @@ -3711,7 +3734,8 @@ char *BPy_BMElem_StringFromHType_ex(const char htype, char ret[32]) if (htype & BM_FACE) ret_ptr += sprintf(ret_ptr, "/%s", BPy_BMFace_Type.tp_name); if (htype & BM_LOOP) ret_ptr += sprintf(ret_ptr, "/%s", BPy_BMLoop_Type.tp_name); ret[0] = '('; - *ret_ptr = ')'; + *ret_ptr++ = ')'; + *ret_ptr = '\0'; return ret; } char *BPy_BMElem_StringFromHType(const char htype) diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c index d6a82ce43ea..df66ef92316 100644 --- a/source/blender/python/intern/bpy_rna.c +++ b/source/blender/python/intern/bpy_rna.c @@ -3324,6 +3324,40 @@ static PyObject *pyrna_prop_path_from_id(BPy_PropertyRNA *self) return ret; } +PyDoc_STRVAR(pyrna_prop_as_bytes_doc, +".. method:: as_bytes()\n" +"\n" +" Returns this string property as a byte rather then a python string.\n" +"\n" +" :return: The string as bytes.\n" +" :rtype: bytes\n" +); +static PyObject *pyrna_prop_as_bytes(BPy_PropertyRNA *self) +{ + + if (RNA_property_type(self->prop) != PROP_STRING) { + PyErr_Format(PyExc_TypeError, + "%.200s.%.200s.as_bytes() must be a string", + RNA_struct_identifier(self->ptr.type), RNA_property_identifier(self->prop)); + return NULL; + } + else { + PyObject *ret; + char buf_fixed[256], *buf; + int buf_len; + + buf = RNA_property_string_get_alloc(&self->ptr, self->prop, buf_fixed, sizeof(buf_fixed), &buf_len); + + ret = PyBytes_FromStringAndSize(buf, buf_len); + + if (buf_fixed != buf) { + MEM_freeN(buf); + } + + return ret; + } +} + PyDoc_STRVAR(pyrna_struct_type_recast_doc, ".. method:: type_recast()\n" "\n" @@ -4685,6 +4719,7 @@ static struct PyMethodDef pyrna_struct_methods[] = { static struct PyMethodDef pyrna_prop_methods[] = { {"path_from_id", (PyCFunction)pyrna_prop_path_from_id, METH_NOARGS, pyrna_prop_path_from_id_doc}, + {"as_bytes", (PyCFunction)pyrna_prop_as_bytes, METH_NOARGS, pyrna_prop_as_bytes_doc}, {"__dir__", (PyCFunction)pyrna_prop_dir, METH_NOARGS, NULL}, {NULL, NULL, 0, NULL} }; diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 31d1fb93477..0d7e3e66946 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -2802,11 +2802,11 @@ static void init_render_surf(Render *re, ObjectRen *obr, int timeoffset) if (ob->parent && (ob->parent->type==OB_LATTICE)) need_orco= 1; - BKE_displist_make_surf(re->scene, ob, &displist, &dm, 1, 0); + BKE_displist_make_surf(re->scene, ob, &displist, &dm, 1, 0, 1); if (dm) { if (need_orco) { - orco= BKE_displist_make_orco(re->scene, ob, dm, 1); + orco= BKE_displist_make_orco(re->scene, ob, dm, 1, 1); if (orco) { set_object_orco(re, ob, orco); } @@ -2852,7 +2852,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) if (ob->type==OB_FONT && cu->str==NULL) return; else if (ob->type==OB_CURVE && cu->nurb.first==NULL) return; - BKE_displist_make_curveTypes_forRender(re->scene, ob, &disp, &dm, 0); + BKE_displist_make_curveTypes_forRender(re->scene, ob, &disp, &dm, 0, 1); dl= disp.first; if (dl==NULL) return; @@ -2877,7 +2877,7 @@ static void init_render_curve(Render *re, ObjectRen *obr, int timeoffset) if (dm) { if (need_orco) { - orco= BKE_displist_make_orco(re->scene, ob, dm, 1); + orco= BKE_displist_make_orco(re->scene, ob, dm, 1, 1); if (orco) { set_object_orco(re, ob, orco); } diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 2af513cebe6..a395d535907 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -119,7 +119,7 @@ void WM_cursor_set (struct wmWindow *win, int curs); void WM_cursor_modal (struct wmWindow *win, int curs); void WM_cursor_restore (struct wmWindow *win); void WM_cursor_wait (bool val); -void WM_cursor_grab_enable(struct wmWindow *win, int wrap, int hide, int bounds[4]); +void WM_cursor_grab_enable(struct wmWindow *win, bool wrap, bool hide, int bounds[4]); void WM_cursor_grab_disable(struct wmWindow *win, int mouse_ungrab_xy[2]); void WM_cursor_time (struct wmWindow *win, int nr); @@ -154,7 +154,7 @@ struct wmEventHandler *WM_event_add_ui_handler( void WM_event_remove_ui_handler(ListBase *handlers, int (*func)(struct bContext *C, const struct wmEvent *event, void *userdata), void (*remove)(struct bContext *C, void *userdata), - void *userdata, int postpone); + void *userdata, const bool postpone); void WM_event_remove_area_handler(struct ListBase *handlers, void *area); struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op); @@ -386,7 +386,6 @@ void WM_jobs_kill_all_except(struct wmWindowManager *wm, void *owner); void WM_jobs_kill_type(struct wmWindowManager *wm, int job_type); int WM_jobs_has_running(struct wmWindowManager *wm); -int WM_jobs_has_running_except(struct wmWindowManager *wm, int job_type); /* clipboard */ char *WM_clipboard_text_get(int selection); diff --git a/source/blender/windowmanager/WM_keymap.h b/source/blender/windowmanager/WM_keymap.h index 49ee759bbf2..6f3b90c00a1 100644 --- a/source/blender/windowmanager/WM_keymap.h +++ b/source/blender/windowmanager/WM_keymap.h @@ -94,7 +94,7 @@ void WM_keymap_restore_item_to_default(struct bContext *C, struct wmKeyMap *key const char *WM_key_event_string(short type); int WM_key_event_operator_id(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, int hotkey, struct wmKeyMap **keymap_r); -char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, const short sloppy, char *str, int len); +char *WM_key_event_operator_string(const struct bContext *C, const char *opname, int opcontext, struct IDProperty *properties, const bool sloppy, char *str, int len); #ifdef __cplusplus } diff --git a/source/blender/windowmanager/intern/wm_cursors.c b/source/blender/windowmanager/intern/wm_cursors.c index f8081cb8012..bf48d9e6561 100644 --- a/source/blender/windowmanager/intern/wm_cursors.c +++ b/source/blender/windowmanager/intern/wm_cursors.c @@ -184,7 +184,7 @@ void WM_cursor_wait(bool val) /** * \param bounds can be NULL */ -void WM_cursor_grab_enable(wmWindow *win, int wrap, int hide, int bounds[4]) +void WM_cursor_grab_enable(wmWindow *win, bool wrap, bool hide, int bounds[4]) { /* Only grab cursor when not running debug. * It helps not to get a stuck WM when hitting a breakpoint diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index d7b642fc5cf..626eeeadfe4 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -987,7 +987,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, } } - WM_cursor_grab_enable(CTX_wm_window(C), wrap, FALSE, bounds); + WM_cursor_grab_enable(CTX_wm_window(C), wrap, false, bounds); } /* cancel UI handlers, typically tooltips that can hang around @@ -2403,9 +2403,17 @@ wmEventHandler *WM_event_add_ui_handler(const bContext *C, ListBase *handlers, handler->ui_handle = func; handler->ui_remove = remove; handler->ui_userdata = userdata; - handler->ui_area = (C) ? CTX_wm_area(C) : NULL; - handler->ui_region = (C) ? CTX_wm_region(C) : NULL; - handler->ui_menu = (C) ? CTX_wm_menu(C) : NULL; + if (C) { + handler->ui_area = CTX_wm_area(C); + handler->ui_region = CTX_wm_region(C); + handler->ui_menu = CTX_wm_menu(C); + } + else { + handler->ui_area = NULL; + handler->ui_region = NULL; + handler->ui_menu = NULL; + } + BLI_addhead(handlers, handler); @@ -2414,7 +2422,7 @@ wmEventHandler *WM_event_add_ui_handler(const bContext *C, ListBase *handlers, /* set "postpone" for win->modalhandlers, this is in a running for () loop in wm_handlers_do() */ void WM_event_remove_ui_handler(ListBase *handlers, - wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata, int postpone) + wmUIHandlerFunc func, wmUIHandlerRemoveFunc remove, void *userdata, const bool postpone) { wmEventHandler *handler; diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index e5963840261..c637b77738e 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -591,16 +591,3 @@ int WM_jobs_has_running(wmWindowManager *wm) return FALSE; } - -int WM_jobs_has_running_except(wmWindowManager *wm, int job_type) -{ - wmJob *wm_job; - - for (wm_job = wm->jobs.first; wm_job; wm_job = wm_job->next) { - if (wm_job->running && wm_job->job_type != job_type) { - return TRUE; - } - } - - return FALSE; -} diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index ff711c5ca4d..aa9af4af154 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -101,7 +101,7 @@ static int wm_keymap_item_equals_result(wmKeyMapItem *a, wmKeyMapItem *b) if (strcmp(a->idname, b->idname) != 0) return 0; - if (!RNA_struct_equals(a->ptr, b->ptr)) + if (!RNA_struct_equals(a->ptr, b->ptr, true)) return 0; if ((a->flag & KMI_INACTIVE) != (b->flag & KMI_INACTIVE)) @@ -874,9 +874,14 @@ static wmKeyMapItem *wm_keymap_item_find_handlers( } #endif - if (kmi->ptr && IDP_EqualsProperties_ex(properties, kmi->ptr->data, is_strict)) { - if (keymap_r) *keymap_r = keymap; - return kmi; + if (kmi->ptr) { + PointerRNA properties_ptr; + RNA_pointer_create(NULL, kmi->ptr->type, properties, &properties_ptr); + + if (RNA_struct_equals(&properties_ptr, kmi->ptr, is_strict)) { + if (keymap_r) *keymap_r = keymap; + return kmi; + } } } else { @@ -958,7 +963,12 @@ static wmKeyMapItem *wm_keymap_item_find( RNA_pointer_create(NULL, ot->srna, properties_default, &opptr); - if (WM_operator_properties_default(&opptr, true)) { + if (WM_operator_properties_default(&opptr, true) || + (ot->prop && RNA_property_is_set(&opptr, ot->prop))) { + /* for operator that has enum menu, unset it so it always matches */ + if (ot->prop) + RNA_property_unset(&opptr, ot->prop); + found = wm_keymap_item_find_props(C, opname, opcontext, properties_default, 0, hotkey, keymap_r); } @@ -972,7 +982,7 @@ static wmKeyMapItem *wm_keymap_item_find( char *WM_key_event_operator_string( const bContext *C, const char *opname, int opcontext, - IDProperty *properties, const short sloppy, char *str, int len) + IDProperty *properties, const bool sloppy, char *str, int len) { wmKeyMapItem *kmi = wm_keymap_item_find(C, opname, opcontext, properties, 0, sloppy, NULL); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index d0f258dc375..1fac48259c1 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -333,7 +333,7 @@ static int wm_macro_modal(bContext *C, wmOperator *op, const wmEvent *event) } } - WM_cursor_grab_enable(CTX_wm_window(C), wrap, FALSE, bounds); + WM_cursor_grab_enable(CTX_wm_window(C), wrap, false, bounds); } } } @@ -1700,7 +1700,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org/development/credits"); uiItemStringO(col, IFACE_("Release Log"), ICON_URL, "WM_OT_url_open", "url", - "http://www.blender.org/development/release-logs/blender-266"); + "http://www.blender.org/development/release-logs/blender-267"); uiItemStringO(col, IFACE_("Manual"), ICON_URL, "WM_OT_url_open", "url", "http://wiki.blender.org/index.php/Doc:2.6/Manual"); uiItemStringO(col, IFACE_("Blender Website"), ICON_URL, "WM_OT_url_open", "url", "http://www.blender.org"); diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 40eb9c673e2..5c4ebfcaac7 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -260,6 +260,7 @@ struct ImBuf *ED_space_image_buffer(struct SpaceImage *sima) {return (struct ImB void ED_space_image_uv_sculpt_update(struct wmWindowManager *wm, struct ToolSettings *settings) {} void ED_screen_set_scene(struct bContext *C, struct Scene *scene) {} +struct MovieClip *ED_space_clip_get_clip(struct SpaceClip *sc) {return (struct MovieClip *) NULL;} void ED_space_clip_set_clip(struct bContext *C, struct SpaceClip *sc, struct MovieClip *clip) {} void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask) {} void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct Mask *mask) {} diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp index 450ae1a16b5..426392305ab 100644 --- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp +++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp @@ -182,7 +182,7 @@ static int BL_KetsjiNextFrame(KX_KetsjiEngine *ketsjiengine, bContext *C, wmWind return exitrequested; } -struct BL_KetsjiNextFrameState { +static struct BL_KetsjiNextFrameState { class KX_KetsjiEngine* ketsjiengine; struct bContext *C; struct wmWindow* win; diff --git a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp index e51daf615b8..e15b8ac942f 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderCanvas.cpp @@ -32,6 +32,7 @@ #include "KX_BlenderCanvas.h" #include "DNA_screen_types.h" +#include "DNA_windowmanager_types.h" #include <stdio.h> #include <assert.h> @@ -256,5 +257,5 @@ void KX_BlenderCanvas::MakeScreenShot(const char *filename) area_dummy.totrct.ymin = m_frame_rect.GetBottom(); area_dummy.totrct.ymax = m_frame_rect.GetTop(); - BL_MakeScreenShot(&area_dummy, filename); + BL_MakeScreenShot(m_win->screen, &area_dummy, filename); } diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp index f808b1b7272..ebf788024c5 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.cpp @@ -60,6 +60,7 @@ #include "DNA_image_types.h" #include "DNA_view3d_types.h" #include "DNA_material_types.h" +#include "DNA_space_types.h" #include "DNA_windowmanager_types.h" #include "BKE_global.h" @@ -68,6 +69,7 @@ #include "BKE_image.h" #include "BLI_path_util.h" +#include "BLI_string.h" extern "C" { #include "IMB_imbuf_types.h" @@ -270,8 +272,6 @@ void BL_NormalMouse(wmWindow *win) { WM_cursor_set(win, CURSOR_STD); } -#define MAX_FILE_LENGTH 512 - /* get shot from frontbuffer sort of a copy from screendump.c */ static unsigned int *screenshot(ScrArea *curarea, int *dumpsx, int *dumpsy) { @@ -296,27 +296,36 @@ static unsigned int *screenshot(ScrArea *curarea, int *dumpsx, int *dumpsy) } /* based on screendump.c::screenshot_exec */ -void BL_MakeScreenShot(ScrArea *curarea, const char *filename) +void BL_MakeScreenShot(bScreen *screen, ScrArea *curarea, const char *filename) { - char path[MAX_FILE_LENGTH]; - strcpy(path,filename); - unsigned int *dumprect; int dumpsx, dumpsy; - dumprect= screenshot(curarea, &dumpsx, &dumpsy); + dumprect = screenshot(curarea, &dumpsx, &dumpsy); + if (dumprect) { - ImBuf *ibuf; + /* initialize image file format data */ + Scene *scene = (screen)? screen->scene: NULL; + ImageFormatData im_format; + + if(scene) + im_format = scene->r.im_format; + else + BKE_imformat_defaults(&im_format); + + /* create file path */ + char path[FILE_MAX]; + BLI_strncpy(path, filename, sizeof(path)); BLI_path_abs(path, G.main->name); - /* BKE_add_image_extension() checks for if extension was already set */ - BKE_add_image_extension_from_type(path, R_IMF_IMTYPE_PNG); /* scene->r.im_format.imtype */ - ibuf= IMB_allocImBuf(dumpsx, dumpsy, 24, 0); - ibuf->rect= dumprect; - ibuf->ftype= PNG; + BKE_add_image_extension_from_type(path, im_format.imtype); + + /* create and save imbuf */ + ImBuf *ibuf = IMB_allocImBuf(dumpsx, dumpsy, 24, 0); + ibuf->rect = dumprect; - IMB_saveiff(ibuf, path, IB_rect); + BKE_imbuf_write_as(ibuf, path, &im_format, false); - ibuf->rect= NULL; + ibuf->rect = NULL; IMB_freeImBuf(ibuf); MEM_freeN(dumprect); } diff --git a/source/gameengine/BlenderRoutines/KX_BlenderGL.h b/source/gameengine/BlenderRoutines/KX_BlenderGL.h index 2545cd34acb..0f35494c73a 100644 --- a/source/gameengine/BlenderRoutines/KX_BlenderGL.h +++ b/source/gameengine/BlenderRoutines/KX_BlenderGL.h @@ -38,13 +38,14 @@ extern "C" { struct wmWindow; struct ARegion; +struct bScreen; // special swapbuffers, that takes care of which area (viewport) needs to be swapped void BL_SwapBuffers(struct wmWindow *win); void BL_warp_pointer(struct wmWindow *win,int x,int y); -void BL_MakeScreenShot(struct ScrArea *curarea, const char *filename); +void BL_MakeScreenShot(struct bScreen *screen, struct ScrArea *curarea, const char *filename); void BL_HideMouse(struct wmWindow *win); void BL_NormalMouse(struct wmWindow *win); diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp index 20c66bd7bc9..abab40cbe67 100644 --- a/source/gameengine/Expressions/ListValue.cpp +++ b/source/gameengine/Expressions/ListValue.cpp @@ -293,7 +293,7 @@ static PyObject *listvalue_buffer_item(PyObject *self, Py_ssize_t index) CValue *cval; if (list==NULL) { - PyErr_SetString(PyExc_SystemError, "val = CList[i], "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val = CList[i], " BGE_PROXY_ERROR_MSG); return NULL; } @@ -350,7 +350,7 @@ static PyObject *listvalue_mapping_subscript(PyObject *self, PyObject *key) { CListValue *list= static_cast<CListValue *>(BGE_PROXY_REF(self)); if (list==NULL) { - PyErr_SetString(PyExc_SystemError, "value = CList[i], "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "value = CList[i], " BGE_PROXY_ERROR_MSG); return NULL; } @@ -398,7 +398,7 @@ static PyObject *listvalue_buffer_concat(PyObject *self, PyObject *other) Py_ssize_t i, numitems, numitems_orig; if (listval==NULL) { - PyErr_SetString(PyExc_SystemError, "CList+other, "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "CList+other, " BGE_PROXY_ERROR_MSG); return NULL; } @@ -447,7 +447,7 @@ static PyObject *listvalue_buffer_concat(PyObject *self, PyObject *other) CListValue* otherval = static_cast<CListValue *>(BGE_PROXY_REF(other)); if (otherval==NULL) { listval_new->Release(); - PyErr_SetString(PyExc_SystemError, "CList+other, "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "CList+other, " BGE_PROXY_ERROR_MSG); return NULL; } @@ -471,7 +471,7 @@ static int listvalue_buffer_contains(PyObject *self_v, PyObject *value) CListValue *self = static_cast<CListValue *>(BGE_PROXY_REF(self_v)); if (self == NULL) { - PyErr_SetString(PyExc_SystemError, "val in CList, "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val in CList, " BGE_PROXY_ERROR_MSG); return -1; } diff --git a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp index 058454ca352..8a6a41f3f99 100644 --- a/source/gameengine/GamePlayer/common/GPC_Canvas.cpp +++ b/source/gameengine/GamePlayer/common/GPC_Canvas.cpp @@ -41,6 +41,18 @@ #include "RAS_IPolygonMaterial.h" #include "GPC_Canvas.h" +#include "BLI_string.h" + +#include "DNA_scene_types.h" +#include "DNA_space_types.h" + +#include "BKE_image.h" + +extern "C" { +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" +} + GPC_Canvas::TBannerId GPC_Canvas::s_bannerId = 0; @@ -425,114 +437,35 @@ GPC_Canvas:: MakeScreenShot( const char* filename ) { - png_structp png_ptr; - png_infop info_ptr; - unsigned char *pixels = 0; - png_bytepp row_pointers = 0; - int i, bytesperpixel = 3, color_type = PNG_COLOR_TYPE_RGB; - FILE *fp = 0; - - png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (!png_ptr) - { - std::cout << "Cannot png_create_write_struct." << std::endl; - return; - } - - info_ptr = png_create_info_struct(png_ptr); - if (!info_ptr) - { - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); - std::cout << "Cannot png_create_info_struct." << std::endl; - return; - } - - if (setjmp(png_jmpbuf(png_ptr))) { - png_destroy_write_struct(&png_ptr, &info_ptr); - delete [] pixels; - delete [] row_pointers; - // printf("Aborting\n"); - if (fp) { - fflush(fp); - fclose(fp); - } - return; - } - // copy image data + unsigned char *pixels = new unsigned char[GetWidth() * GetHeight() * 4]; - pixels = new unsigned char[GetWidth() * GetHeight() * bytesperpixel * sizeof(unsigned char)]; if (!pixels) { std::cout << "Cannot allocate pixels array" << std::endl; return; } - glReadPixels(0, 0, GetWidth(), GetHeight(), GL_RGB, GL_UNSIGNED_BYTE, pixels); - - fp = fopen(filename, "wb"); - if (!fp) - { - std::cout << "Couldn't open " << filename << " for writing." << std::endl; - longjmp(png_jmpbuf(png_ptr), 1); - } - - png_init_io(png_ptr, fp); + glReadPixels(0, 0, GetWidth(), GetHeight(), GL_RGBA, GL_UNSIGNED_BYTE, pixels); -#if 0 - png_set_filter(png_ptr, 0, - PNG_FILTER_NONE | PNG_FILTER_VALUE_NONE | - PNG_FILTER_SUB | PNG_FILTER_VALUE_SUB | - PNG_FILTER_UP | PNG_FILTER_VALUE_UP | - PNG_FILTER_AVG | PNG_FILTER_VALUE_AVG | - PNG_FILTER_PAETH | PNG_FILTER_VALUE_PAETH| - PNG_ALL_FILTERS); - - png_set_compression_level(png_ptr, Z_BEST_COMPRESSION); -#endif + // initialize image file format data + ImageFormatData im_format; + BKE_imformat_defaults(&im_format); - // png image settings - png_set_IHDR(png_ptr, - info_ptr, - GetWidth(), - GetHeight(), - 8, - color_type, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - - // write the file header information - png_write_info(png_ptr, info_ptr); - - // allocate memory for an array of row-pointers - row_pointers = new png_bytep [(GetHeight() * sizeof(png_bytep))]; - if (!row_pointers) - { - std::cout << "Cannot allocate row-pointers array" << std::endl; - longjmp(png_jmpbuf(png_ptr), 1); - } + // create file path + char path[FILE_MAX]; + BLI_strncpy(path, filename, sizeof(path)); + BKE_add_image_extension_from_type(path, im_format.imtype); - // set the individual row-pointers to point at the correct offsets - for (i = 0; i < GetHeight(); i++) { - row_pointers[GetHeight()-1-i] = (png_bytep) - ((unsigned char *)pixels + (i * GetWidth()) * bytesperpixel * sizeof(unsigned char)); - } + // create and save imbuf + ImBuf *ibuf = IMB_allocImBuf(GetWidth(), GetHeight(), 24, 0); + ibuf->rect = (unsigned int*)pixels; - // write out the entire image data in one call - png_write_image(png_ptr, row_pointers); + BKE_imbuf_write_as(ibuf, path, &im_format, false); - // write the additional chunks to the PNG file (not really needed) - png_write_end(png_ptr, info_ptr); + ibuf->rect = NULL; + IMB_freeImBuf(ibuf); // clean up delete [] (pixels); - delete [] (row_pointers); - png_destroy_write_struct(&png_ptr, &info_ptr); - - if (fp) - { - fflush(fp); - fclose(fp); - } } diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp index 98da18dcc68..172440cfcb6 100644 --- a/source/gameengine/Ketsji/KX_GameObject.cpp +++ b/source/gameengine/Ketsji/KX_GameObject.cpp @@ -1572,7 +1572,7 @@ static int mathutils_kxgameob_vector_set_index(BaseMathObject *bmo, int subtype, return mathutils_kxgameob_vector_set(bmo, subtype); } -Mathutils_Callback mathutils_kxgameob_vector_cb = { +static Mathutils_Callback mathutils_kxgameob_vector_cb = { mathutils_kxgameob_generic_check, mathutils_kxgameob_vector_get, mathutils_kxgameob_vector_set, @@ -1628,7 +1628,7 @@ static int mathutils_kxgameob_matrix_set(BaseMathObject *bmo, int subtype) return 0; } -Mathutils_Callback mathutils_kxgameob_matrix_cb = { +static Mathutils_Callback mathutils_kxgameob_matrix_cb = { mathutils_kxgameob_generic_check, mathutils_kxgameob_matrix_get, mathutils_kxgameob_matrix_set, @@ -1800,7 +1800,7 @@ static PyObject *Map_GetItem(PyObject *self_v, PyObject *item) PyObject *pyconvert; if (self == NULL) { - PyErr_SetString(PyExc_SystemError, "val = gameOb[key]: KX_GameObject, "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val = gameOb[key]: KX_GameObject, " BGE_PROXY_ERROR_MSG); return NULL; } @@ -1834,7 +1834,7 @@ static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) PyErr_Clear(); if (self == NULL) { - PyErr_SetString(PyExc_SystemError, "gameOb[key] = value: KX_GameObject, "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "gameOb[key] = value: KX_GameObject, " BGE_PROXY_ERROR_MSG); return -1; } @@ -1919,7 +1919,7 @@ static int Seq_Contains(PyObject *self_v, PyObject *value) KX_GameObject* self = static_cast<KX_GameObject*>BGE_PROXY_REF(self_v); if (self == NULL) { - PyErr_SetString(PyExc_SystemError, "val in gameOb: KX_GameObject, "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val in gameOb: KX_GameObject, " BGE_PROXY_ERROR_MSG); return -1; } diff --git a/source/gameengine/Ketsji/KX_ObjectActuator.cpp b/source/gameengine/Ketsji/KX_ObjectActuator.cpp index d02554e185e..9d6c8d250c7 100644 --- a/source/gameengine/Ketsji/KX_ObjectActuator.cpp +++ b/source/gameengine/Ketsji/KX_ObjectActuator.cpp @@ -496,7 +496,7 @@ static int mathutils_obactu_vector_set_index(BaseMathObject *bmo, int subtype, i return mathutils_obactu_vector_set(bmo, subtype); } -Mathutils_Callback mathutils_obactu_vector_cb = { +static Mathutils_Callback mathutils_obactu_vector_cb = { mathutils_obactu_generic_check, mathutils_obactu_vector_get, mathutils_obactu_vector_set, diff --git a/source/gameengine/Ketsji/KX_PolyProxy.cpp b/source/gameengine/Ketsji/KX_PolyProxy.cpp index 840ffdde165..eaedc752201 100644 --- a/source/gameengine/Ketsji/KX_PolyProxy.cpp +++ b/source/gameengine/Ketsji/KX_PolyProxy.cpp @@ -103,7 +103,7 @@ KX_PolyProxy::~KX_PolyProxy() // stuff for cvalue related things CValue* KX_PolyProxy::Calc(VALUE_OPERATOR, CValue *) { return NULL;} CValue* KX_PolyProxy::CalcFinal(VALUE_DATA_TYPE, VALUE_OPERATOR, CValue *) { return NULL;} -STR_String sPolyName="polygone"; +static STR_String sPolyName = "polygone"; const STR_String & KX_PolyProxy::GetText() {return sPolyName;}; double KX_PolyProxy::GetNumber() { return -1;} STR_String& KX_PolyProxy::GetName() { return sPolyName;} diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index edbb0537559..fb3e6c58027 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -74,7 +74,7 @@ static Py_ssize_t KX_PythonSeq_len( PyObject *self ) PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); if (self_plus==NULL) { - PyErr_SetString(PyExc_SystemError, "len(seq): "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "len(seq): " BGE_PROXY_ERROR_MSG); return -1; } @@ -105,7 +105,7 @@ static PyObject *KX_PythonSeq_getIndex(PyObject *self, Py_ssize_t index) PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); if (self_plus==NULL) { - PyErr_SetString(PyExc_SystemError, "val = seq[i]: "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val = seq[i]: " BGE_PROXY_ERROR_MSG); return NULL; } @@ -269,7 +269,7 @@ static PyObject *KX_PythonSeq_subscript(PyObject *self, PyObject *key) PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); if (self_plus==NULL) { - PyErr_SetString(PyExc_SystemError, "val = seq[key], KX_PythonSeq: "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val = seq[key], KX_PythonSeq: " BGE_PROXY_ERROR_MSG); return NULL; } @@ -299,7 +299,7 @@ static int KX_PythonSeq_contains(PyObject *self, PyObject *key) PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); if (self_plus==NULL) { - PyErr_SetString(PyExc_SystemError, "key in seq, KX_PythonSeq: "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "key in seq, KX_PythonSeq: " BGE_PROXY_ERROR_MSG); return -1; } if (!PyUnicode_Check(key)) { @@ -362,7 +362,7 @@ PyMethodDef KX_PythonSeq_methods[] = { static PyObject *KX_PythonSeq_getIter(KX_PythonSeq *self) { if (BGE_PROXY_REF(self->base)==NULL) { - PyErr_SetString(PyExc_SystemError, "for i in seq: "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "for i in seq: " BGE_PROXY_ERROR_MSG); return NULL; } diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 92e064c6e91..adc0aa194af 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -2064,7 +2064,7 @@ static PyObject *Map_GetItem(PyObject *self_v, PyObject *item) PyObject *pyconvert; if (self == NULL) { - PyErr_SetString(PyExc_SystemError, "val = scene[key]: KX_Scene, "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val = scene[key]: KX_Scene, " BGE_PROXY_ERROR_MSG); return NULL; } @@ -2094,7 +2094,7 @@ static int Map_SetItem(PyObject *self_v, PyObject *key, PyObject *val) PyErr_Clear(); if (self == NULL) { - PyErr_SetString(PyExc_SystemError, "scene[key] = value: KX_Scene, "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "scene[key] = value: KX_Scene, " BGE_PROXY_ERROR_MSG); return -1; } @@ -2141,7 +2141,7 @@ static int Seq_Contains(PyObject *self_v, PyObject *value) KX_Scene* self = static_cast<KX_Scene*>BGE_PROXY_REF(self_v); if (self == NULL) { - PyErr_SetString(PyExc_SystemError, "val in scene: KX_Scene, "BGE_PROXY_ERROR_MSG); + PyErr_SetString(PyExc_SystemError, "val in scene: KX_Scene, " BGE_PROXY_ERROR_MSG); return -1; } diff --git a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp index e093b7cd722..79ce8538210 100644 --- a/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp +++ b/source/gameengine/Rasterizer/RAS_2DFilterManager.cpp @@ -24,7 +24,6 @@ * \ingroup bgerast */ - #define STRINGIFY(A) #A #include "RAS_OpenGLFilters/RAS_Blur2DFilter.h" diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Blur2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Blur2DFilter.h index c2595fb0d26..3f1644a5c60 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Blur2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Blur2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_BLUR2DFILTER_H__ #define __RAS_BLUR2DFILTER_H__ -const char * BlurFragmentShader=STRINGIFY( +static const char *BlurFragmentShader = STRINGIFY( uniform sampler2D bgl_RenderedTexture; uniform vec2 bgl_TextureCoordinateOffset[9]; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Dilation2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Dilation2DFilter.h index 12b815a1519..4e863cb6f8d 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Dilation2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Dilation2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_DILATION2DFILTER_H__ #define __RAS_DILATION2DFILTER_H__ -const char * DilationFragmentShader=STRINGIFY( +static const char *DilationFragmentShader = STRINGIFY( uniform sampler2D bgl_RenderedTexture; uniform vec2 bgl_TextureCoordinateOffset[9]; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h index eaefd5c13fa..56e2c22fe2e 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Erosion2DFilter.h @@ -32,9 +32,9 @@ #ifndef __RAS_EROSION2DFILTER_H__ #define __RAS_EROSION2DFILTER_H__ -const char * ErosionFragmentShader = STRINGIFY( - uniform sampler2D bgl_RenderedTexture; - uniform vec2 bgl_TextureCoordinateOffset[9]; +static const char *ErosionFragmentShader = STRINGIFY( +uniform sampler2D bgl_RenderedTexture; +uniform vec2 bgl_TextureCoordinateOffset[9]; void main(void) { diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_GrayScale2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_GrayScale2DFilter.h index f3c3aece7d5..932d5b16fed 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_GrayScale2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_GrayScale2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_GRAYSCALE2DFILTER_H__ #define __RAS_GRAYSCALE2DFILTER_H__ -const char * GrayScaleFragmentShader=STRINGIFY( +static const char *GrayScaleFragmentShader = STRINGIFY( uniform sampler2D bgl_RenderedTexture; void main(void) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Invert2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Invert2DFilter.h index c04d9543e89..dce303916ea 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Invert2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Invert2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_INVERT2DFILTER_H__ #define __RAS_INVERT2DFILTER_H__ -const char * InvertFragmentShader=STRINGIFY( +static const char *InvertFragmentShader = STRINGIFY( uniform sampler2D bgl_RenderedTexture; void main(void) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Laplacian2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Laplacian2DFilter.h index 47f7d80d9d7..9ec5092817d 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Laplacian2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Laplacian2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_LAPLACIAN2DFILTER_H__ #define __RAS_LAPLACIAN2DFILTER_H__ -const char * LaplacionFragmentShader=STRINGIFY( +static const char *LaplacionFragmentShader = STRINGIFY( uniform sampler2D bgl_RenderedTexture; uniform vec2 bgl_TextureCoordinateOffset[9]; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Prewitt2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Prewitt2DFilter.h index 8b2fdc71cfb..4ae6009fdeb 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Prewitt2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Prewitt2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_PREWITT2DFILTER_H__ #define __RAS_PREWITT2DFILTER_H__ -const char * PrewittFragmentShader=STRINGIFY( +static const char *PrewittFragmentShader = STRINGIFY( uniform sampler2D bgl_RenderedTexture; uniform vec2 bgl_TextureCoordinateOffset[9]; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sepia2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sepia2DFilter.h index b38d14a3746..16b4e71dfdb 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sepia2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sepia2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_SEPIA2DFILTER_H__ #define __RAS_SEPIA2DFILTER_H__ -const char * SepiaFragmentShader=STRINGIFY( +static const char *SepiaFragmentShader = STRINGIFY( uniform sampler2D bgl_RenderedTexture; void main(void) diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sharpen2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sharpen2DFilter.h index 2e0edae61c4..7512393815b 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sharpen2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sharpen2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_SHARPEN2DFILTER_H__ #define __RAS_SHARPEN2DFILTER_H__ -const char * SharpenFragmentShader=STRINGIFY( +static const char *SharpenFragmentShader = STRINGIFY( uniform sampler2D bgl_RenderedTexture; uniform vec2 bgl_TextureCoordinateOffset[9]; @@ -53,4 +53,3 @@ void main(void) } ); #endif - diff --git a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sobel2DFilter.h b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sobel2DFilter.h index ba30e497923..088ac10a56a 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sobel2DFilter.h +++ b/source/gameengine/Rasterizer/RAS_OpenGLFilters/RAS_Sobel2DFilter.h @@ -32,7 +32,7 @@ #ifndef __RAS_SOBEL2DFILTER_H__ #define __RAS_SOBEL2DFILTER_H__ -const char * SobelFragmentShader=STRINGIFY( +static const char *SobelFragmentShader = STRINGIFY( uniform sampler2D bgl_RenderedTexture; uniform vec2 bgl_TextureCoordinateOffset[9]; diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp index 3de77951fa7..c7779c209ba 100644 --- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp +++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_StorageVBO.cpp @@ -35,7 +35,7 @@ VBO::VBO(RAS_DisplayArray *data, unsigned int indices) this->data = data; this->size = data->m_vertex.size(); this->indices = indices; - this->stride = 32*sizeof(GLfloat); // ATI cards really like 32byte aligned VBOs, so we add a little padding + this->stride = sizeof(RAS_TexVert); // Determine drawmode if (data->m_type == data->QUAD) @@ -54,11 +54,11 @@ VBO::VBO(RAS_DisplayArray *data, unsigned int indices) UpdateData(); // Establish offsets - this->vertex_offset = 0; - this->normal_offset = (void*)(3*sizeof(GLfloat)); - this->tangent_offset = (void*)(6*sizeof(GLfloat)); - this->color_offset = (void*)(10*sizeof(GLfloat)); - this->uv_offset = (void*)(11*sizeof(GLfloat)); + this->vertex_offset = (void*)(((RAS_TexVert*)0)->getXYZ()); + this->normal_offset = (void*)(((RAS_TexVert*)0)->getNormal()); + this->tangent_offset = (void*)(((RAS_TexVert*)0)->getTangent()); + this->color_offset = (void*)(((RAS_TexVert*)0)->getRGBA());; + this->uv_offset = (void*)(((RAS_TexVert*)0)->getUV(0)); } VBO::~VBO() @@ -69,36 +69,15 @@ VBO::~VBO() void VBO::UpdateData() { - unsigned int i, j, k; - glBindBufferARB(GL_ARRAY_BUFFER_ARB, this->vbo_id); - glBufferData(GL_ARRAY_BUFFER, this->stride*this->size, NULL, GL_STATIC_DRAW); - - // Map the buffer - GLfloat *vbo_map = (GLfloat*)glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - - // Gather data - for (i = 0, j = 0; i < data->m_vertex.size(); i++, j += this->stride/sizeof(GLfloat)) - { - memcpy(&vbo_map[j], data->m_vertex[i].getXYZ(), sizeof(float)*3); - memcpy(&vbo_map[j+3], data->m_vertex[i].getNormal(), sizeof(float)*3); - memcpy(&vbo_map[j+6], data->m_vertex[i].getTangent(), sizeof(float)*4); - memcpy(&vbo_map[j+10], data->m_vertex[i].getRGBA(), sizeof(char)*4); - - for (k = 0; k < RAS_TexVert::MAX_UNIT; k++) - memcpy(&vbo_map[j+11+(k*2)], data->m_vertex[i].getUV(k), sizeof(float)*2); - } - - glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); + glBufferData(GL_ARRAY_BUFFER, this->stride*this->size, &this->data->m_vertex[0], GL_STATIC_DRAW); } void VBO::UpdateIndices() { - int space = data->m_index.size() * sizeof(GLushort); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, this->ibo); - - // Upload Data to VBO - glBufferData(GL_ELEMENT_ARRAY_BUFFER, space, &data->m_index[0], GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, data->m_index.size() * sizeof(GLushort), + &data->m_index[0], GL_STATIC_DRAW); } void VBO::Draw(int texco_num, RAS_IRasterizer::TexCoGen* texco, int attrib_num, RAS_IRasterizer::TexCoGen* attrib, int *attrib_layer, bool multi) diff --git a/source/gameengine/Rasterizer/RAS_TexVert.h b/source/gameengine/Rasterizer/RAS_TexVert.h index a91d2c7f848..8d08549d97e 100644 --- a/source/gameengine/Rasterizer/RAS_TexVert.h +++ b/source/gameengine/Rasterizer/RAS_TexVert.h @@ -56,9 +56,10 @@ class RAS_TexVert short m_softBodyIndex; //2 unsigned int m_unit; // 4 unsigned int m_origindex; // 4 + char m_padding[8]; // 8 //--------- - // 120 - // 32 bytes total size, fits nice = 120 = not fit nice. + // 128 + // 32 bytes alignment improves performance on ATI cards. public: enum { diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 016020048e9..d251f4f7bcb 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -288,9 +288,9 @@ inline ImageRender * getImageRender (PyImage *self) // python methods // Blender Scene type -BlendType<KX_Scene> sceneType ("KX_Scene"); +static BlendType<KX_Scene> sceneType ("KX_Scene"); // Blender Camera type -BlendType<KX_Camera> cameraType ("KX_Camera"); +static BlendType<KX_Camera> cameraType ("KX_Camera"); // object initialization @@ -398,8 +398,7 @@ static PyGetSetDef imageRenderGetSets[] = // define python type -PyTypeObject ImageRenderType = -{ +PyTypeObject ImageRenderType = { PyVarObject_HEAD_INIT(NULL, 0) "VideoTexture.ImageRender", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ @@ -733,8 +732,7 @@ ImageRender::ImageRender (KX_Scene *scene, KX_GameObject *observer, KX_GameObjec // define python type -PyTypeObject ImageMirrorType = -{ +PyTypeObject ImageMirrorType = { PyVarObject_HEAD_INIT(NULL, 0) "VideoTexture.ImageMirror", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ diff --git a/source/gameengine/VideoTexture/ImageViewport.cpp b/source/gameengine/VideoTexture/ImageViewport.cpp index 19d0289be20..18095ea631d 100644 --- a/source/gameengine/VideoTexture/ImageViewport.cpp +++ b/source/gameengine/VideoTexture/ImageViewport.cpp @@ -358,8 +358,7 @@ static PyGetSetDef imageViewportGetSets[] = // define python type -PyTypeObject ImageViewportType = -{ +PyTypeObject ImageViewportType = { PyVarObject_HEAD_INIT(NULL, 0) "VideoTexture.ImageViewport", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ diff --git a/source/gameengine/VideoTexture/Texture.cpp b/source/gameengine/VideoTexture/Texture.cpp index ebad7a92437..aebc2aeef01 100644 --- a/source/gameengine/VideoTexture/Texture.cpp +++ b/source/gameengine/VideoTexture/Texture.cpp @@ -63,8 +63,8 @@ // Blender GameObject type -BlendType<KX_GameObject> gameObjectType ("KX_GameObject"); -BlendType<KX_LightObject> lightObjectType ("KX_LightObject"); +static BlendType<KX_GameObject> gameObjectType ("KX_GameObject"); +static BlendType<KX_LightObject> lightObjectType ("KX_LightObject"); // load texture diff --git a/source/gameengine/VideoTexture/Texture.h b/source/gameengine/VideoTexture/Texture.h index 157eea56c09..c85b1228864 100644 --- a/source/gameengine/VideoTexture/Texture.h +++ b/source/gameengine/VideoTexture/Texture.h @@ -94,7 +94,4 @@ short getMaterialID(PyObject *obj, const char *name); // Exceptions extern ExceptionID MaterialNotAvail; -// object type -extern BlendType<KX_GameObject> gameObjectType; - #endif diff --git a/source/gameengine/VideoTexture/VideoBase.h b/source/gameengine/VideoTexture/VideoBase.h index 8d64980c9c2..51f025909fd 100644 --- a/source/gameengine/VideoTexture/VideoBase.h +++ b/source/gameengine/VideoTexture/VideoBase.h @@ -199,6 +199,9 @@ int Video_setRepeat(PyImage *self, PyObject *value, void *closure); PyObject *Video_getFrameRate(PyImage *self, void *closure); int Video_setFrameRate(PyImage *self, PyObject *value, void *closure); +/* py api */ +extern PyTypeObject ImageRenderType; +extern PyTypeObject ImageMirrorType; +extern PyTypeObject ImageViewportType; -#endif - +#endif /* __VIDEOBASE_H__ */ diff --git a/source/gameengine/VideoTexture/blendVideoTex.cpp b/source/gameengine/VideoTexture/blendVideoTex.cpp index e23bd1a3231..ab6dca0958f 100644 --- a/source/gameengine/VideoTexture/blendVideoTex.cpp +++ b/source/gameengine/VideoTexture/blendVideoTex.cpp @@ -134,11 +134,6 @@ extern PyTypeObject FilterRGBA32Type; extern PyTypeObject FilterBGR24Type; extern PyTypeObject ImageBuffType; extern PyTypeObject ImageMixType; -extern PyTypeObject ImageRenderType; -extern PyTypeObject ImageMirrorType; -extern PyTypeObject ImageViewportType; -extern PyTypeObject ImageViewportType; - static void registerAllTypes(void) { |