Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wilkins <Jason.A.Wilkins@gmail.com>2014-10-07 19:39:17 +0400
committerJason Wilkins <Jason.A.Wilkins@gmail.com>2014-10-07 19:39:17 +0400
commit189c2e9277d4abd3b750a5a60ef42549dcfe359d (patch)
tree1430a845f4aab56b9133c3d8c6ffac09ee6dd92a
parent771bad9c6abaad4b742935e5d55067f281287650 (diff)
parent1519b6a23e0341e25bf5a5c714f9f3d119ab8781 (diff)
Merge branch 'master' into soc-2014-viewport_contextsoc-2014-viewport_context
-rw-r--r--CMakeLists.txt7
-rwxr-xr-xbuild_files/build_environment/install_deps.sh19
-rw-r--r--build_files/buildbot/config/user-config-glibc211-i686.py2
-rw-r--r--build_files/buildbot/config/user-config-glibc211-x86_64.py2
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-i686.py2
-rw-r--r--build_files/buildbot/config/user-config-player-glibc211-x86_64.py2
-rwxr-xr-xbuild_files/cmake/cmake_consistency_check.py2
-rw-r--r--build_files/scons/tools/btools.py7
-rwxr-xr-xbuild_files/utils/build_tgz.sh9
-rw-r--r--doc/python_api/examples/bpy.props.5.py2
-rw-r--r--doc/python_api/examples/bpy.types.Operator.5.py2
-rw-r--r--doc/python_api/examples/bpy.types.bpy_prop_collection.foreach_get.py1
-rw-r--r--doc/python_api/sphinx_doc_gen.py70
-rwxr-xr-xdoc/python_api/sphinx_doc_gen.sh6
-rw-r--r--doc/python_api/sphinx_doc_gen_monkeypatch.py38
-rw-r--r--extern/libmv/CMakeLists.txt28
-rw-r--r--extern/libmv/SConscript6
-rwxr-xr-xextern/libmv/bundle.sh32
-rw-r--r--extern/libmv/intern/camera_intrinsics.cc354
-rw-r--r--extern/libmv/intern/camera_intrinsics.h138
-rw-r--r--extern/libmv/intern/detector.cc148
-rw-r--r--extern/libmv/intern/detector.h77
-rw-r--r--extern/libmv/intern/homography.cc59
-rw-r--r--extern/libmv/intern/homography.h43
-rw-r--r--extern/libmv/intern/image.cc272
-rw-r--r--extern/libmv/intern/image.h99
-rw-r--r--extern/libmv/intern/logging.cc55
-rw-r--r--extern/libmv/intern/logging.h47
-rw-r--r--extern/libmv/intern/reconstruction.cc530
-rw-r--r--extern/libmv/intern/reconstruction.h100
-rw-r--r--extern/libmv/intern/region.h43
-rw-r--r--extern/libmv/intern/stub.cc330
-rw-r--r--extern/libmv/intern/track_region.cc177
-rw-r--r--extern/libmv/intern/track_region.h81
-rw-r--r--extern/libmv/intern/tracks.cc52
-rw-r--r--extern/libmv/intern/tracks.h51
-rw-r--r--extern/libmv/intern/utildefines.h (renamed from extern/libmv/libmv-capi_intern.h)23
-rw-r--r--extern/libmv/libmv-capi.cc1185
-rw-r--r--extern/libmv/libmv-capi.h187
-rw-r--r--extern/libmv/libmv-capi_stub.cc293
-rw-r--r--extern/libmv/libmv-util.cc309
-rw-r--r--extern/libmv/libmv-util.h69
-rw-r--r--extern/libmv/libmv/simple_pipeline/bundle.cc2
-rw-r--r--extern/libmv/third_party/ceres/CMakeLists.txt106
-rw-r--r--extern/libmv/third_party/ceres/ChangeLog899
-rw-r--r--extern/libmv/third_party/ceres/SConscript15
-rwxr-xr-xextern/libmv/third_party/ceres/bundle.sh28
-rw-r--r--extern/libmv/third_party/ceres/files.txt24
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/c_api.h3
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/ceres.h9
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h2
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/cost_function.h6
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/cost_function_to_functor.h4
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/covariance.h78
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/crs_matrix.h3
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/gradient_problem.h127
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/gradient_problem_solver.h365
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/disable_warnings.h44
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/numeric_diff.h9
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/internal/reenable_warnings.h38
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/iteration_callback.h3
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/jet.h11
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/local_parameterization.h30
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/loss_function.h5
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/normal_prior.h3
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/numeric_diff_functor.h351
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/ordered_groups.h28
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/problem.h14
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/solver.h68
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/types.h19
-rw-r--r--extern/libmv/third_party/ceres/include/ceres/version.h49
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/CMakeLists.txt287
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/array_utils.cc17
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/array_utils.h15
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc109
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h18
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_random_access_diagonal_matrix.cc40
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_random_access_diagonal_matrix.h9
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc41
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.h22
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/callbacks.cc109
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/callbacks.h71
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.cc10
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.cc17
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.cc56
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.h15
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/covariance_impl.cc367
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/covariance_impl.h4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/cxsparse.h7
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/dynamic_compressed_row_jacobian_writer.cc11
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc11
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/gradient_problem.cc81
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/gradient_problem_evaluator.h98
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/gradient_problem_solver.cc270
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/graph.h68
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h7
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc1
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.cc5
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search_preprocessor.cc106
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/line_search_preprocessor.h50
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/linear_solver.cc44
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/linear_solver.h12
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/local_parameterization.cc44
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/loss_function.cc35
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/minimizer.cc16
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/minimizer.h35
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.cc27
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.h5
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/preconditioner.cc10
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/preconditioner.h9
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/preprocessor.cc113
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/preprocessor.h119
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/problem.cc10
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc10
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/problem_impl.h5
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/program.cc255
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/program.h58
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/reorder_program.cc578
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/reorder_program.h101
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.cc302
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h40
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.cc30
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.h4
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/single_linkage_clustering.cc2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/single_linkage_clustering.h2
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/small_blas.h38
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/solver.cc499
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc1851
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/solver_impl.h228
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/solver_utils.cc78
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/solver_utils.h58
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.cc250
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h43
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/suitesparse.h17
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.cc13
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/trust_region_preprocessor.cc358
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/trust_region_preprocessor.h50
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/types.cc14
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/visibility.cc5
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/visibility.h5
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.cc12
-rw-r--r--extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h5
-rw-r--r--extern/lzo/minilzo/README.LZO9
-rw-r--r--extern/lzo/minilzo/lzoconf.h216
-rw-r--r--extern/lzo/minilzo/lzodefs.h2296
-rw-r--r--extern/lzo/minilzo/minilzo.c3776
-rw-r--r--extern/lzo/minilzo/minilzo.h26
-rw-r--r--intern/atomic/atomic_ops.h197
-rw-r--r--intern/cycles/CMakeLists.txt24
-rw-r--r--intern/cycles/SConscript3
-rw-r--r--intern/cycles/app/io_export_cycles_xml.py21
-rw-r--r--intern/cycles/blender/CCL_api.h4
-rw-r--r--intern/cycles/blender/CMakeLists.txt1
-rw-r--r--intern/cycles/blender/addon/__init__.py1
-rw-r--r--intern/cycles/blender/addon/properties.py2
-rw-r--r--intern/cycles/blender/addon/ui.py9
-rw-r--r--intern/cycles/blender/addon/version_update.py29
-rw-r--r--intern/cycles/blender/blender_logging.cpp65
-rw-r--r--intern/cycles/blender/blender_session.cpp11
-rw-r--r--intern/cycles/blender/blender_shader.cpp96
-rw-r--r--intern/cycles/device/device_cpu.cpp5
-rw-r--r--intern/cycles/device/device_cuda.cpp8
-rw-r--r--intern/cycles/device/device_memory.h5
-rw-r--r--intern/cycles/device/device_opencl.cpp6
-rw-r--r--intern/cycles/kernel/CMakeLists.txt11
-rw-r--r--intern/cycles/kernel/SConscript3
-rw-r--r--intern/cycles/kernel/closure/bsdf.h27
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h145
-rw-r--r--intern/cycles/kernel/closure/bsdf_westin.h180
-rw-r--r--intern/cycles/kernel/geom/geom_bvh.h116
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_shadow.h2
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_traversal.h12
-rw-r--r--intern/cycles/kernel/geom/geom_bvh_volume.h322
-rw-r--r--intern/cycles/kernel/geom/geom_motion_triangle.h2
-rw-r--r--intern/cycles/kernel/geom/geom_triangle.h2
-rw-r--r--intern/cycles/kernel/kernel.cu4
-rw-r--r--intern/cycles/kernel/kernel_bake.h4
-rw-r--r--intern/cycles/kernel/kernel_compat_cpu.h7
-rw-r--r--intern/cycles/kernel/kernel_compat_opencl.h12
-rw-r--r--intern/cycles/kernel/kernel_debug.h38
-rw-r--r--intern/cycles/kernel/kernel_path.h124
-rw-r--r--intern/cycles/kernel/kernel_path_state.h4
-rw-r--r--intern/cycles/kernel/kernel_shader.h10
-rw-r--r--intern/cycles/kernel/kernel_shadow.h14
-rw-r--r--intern/cycles/kernel/kernel_textures.h2
-rw-r--r--intern/cycles/kernel/kernel_types.h34
-rw-r--r--intern/cycles/kernel/kernel_volume.h82
-rw-r--r--intern/cycles/kernel/osl/SConscript3
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp15
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h4
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h1
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp4
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp3
-rw-r--r--intern/cycles/kernel/shaders/node_brick_texture.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_fresnel.h6
-rw-r--r--intern/cycles/kernel/shaders/node_geometry.osl2
-rw-r--r--intern/cycles/kernel/shaders/node_image_texture.osl4
-rw-r--r--intern/cycles/kernel/shaders/node_musgrave_texture.osl24
-rw-r--r--intern/cycles/kernel/shaders/node_texture.h6
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h2
-rw-r--r--intern/cycles/kernel/svm/svm_image.h4
-rw-r--r--intern/cycles/kernel/svm/svm_noise.h49
-rw-r--r--intern/cycles/kernel/svm/svm_types.h2
-rw-r--r--intern/cycles/render/buffers.cpp8
-rw-r--r--intern/cycles/render/camera.cpp74
-rw-r--r--intern/cycles/render/camera.h3
-rw-r--r--intern/cycles/render/film.cpp13
-rw-r--r--intern/cycles/render/graph.cpp100
-rw-r--r--intern/cycles/render/graph.h3
-rw-r--r--intern/cycles/render/image.cpp8
-rw-r--r--intern/cycles/render/mesh.cpp19
-rw-r--r--intern/cycles/render/mesh.h4
-rw-r--r--intern/cycles/render/object.cpp52
-rw-r--r--intern/cycles/render/object.h1
-rw-r--r--intern/cycles/render/scene.cpp18
-rw-r--r--intern/cycles/render/scene.h2
-rw-r--r--intern/cycles/render/shader.h8
-rw-r--r--intern/cycles/render/tile.cpp4
-rw-r--r--intern/cycles/util/CMakeLists.txt2
-rw-r--r--intern/cycles/util/util_boundbox.h9
-rw-r--r--intern/cycles/util/util_color.h2
-rw-r--r--intern/cycles/util/util_logging.cpp33
-rw-r--r--intern/cycles/util/util_logging.h53
-rw-r--r--intern/cycles/util/util_types.h13
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm5
-rw-r--r--intern/guardedalloc/intern/mallocn.c1
-rw-r--r--intern/guardedalloc/intern/mallocn_intern.h7
-rw-r--r--intern/guardedalloc/intern/mallocn_lockfree_impl.c34
-rw-r--r--intern/opennl/extern/ONL_opennl.h18
-rw-r--r--intern/opennl/intern/opennl.c102
-rw-r--r--intern/opennl/superlu/scolumn_bmod.c24
-rw-r--r--intern/opennl/superlu/scopy_to_ucol.c6
-rw-r--r--intern/opennl/superlu/sgssv.c2
-rw-r--r--intern/opennl/superlu/sgstrf.c10
-rw-r--r--intern/opennl/superlu/sgstrs.c26
-rw-r--r--intern/opennl/superlu/smemory.c108
-rw-r--r--intern/opennl/superlu/smyblas2.c32
-rw-r--r--intern/opennl/superlu/spanel_bmod.c22
-rw-r--r--intern/opennl/superlu/spanel_dfs.c6
-rw-r--r--intern/opennl/superlu/spivotL.c12
-rw-r--r--intern/opennl/superlu/spruneL.c4
-rw-r--r--intern/opennl/superlu/ssnode_bmod.c12
-rw-r--r--intern/opennl/superlu/ssp_blas2.c34
-rw-r--r--intern/opennl/superlu/ssp_blas3.c8
-rw-r--r--intern/opennl/superlu/ssp_defs.h100
-rw-r--r--intern/opennl/superlu/strsv.c6
-rw-r--r--intern/opennl/superlu/sutil.c76
-rw-r--r--intern/opennl/superlu/util.c14
-rw-r--r--intern/opennl/superlu/util.h4
-rw-r--r--release/datafiles/blender_icons.svg21
m---------release/datafiles/locale0
-rw-r--r--release/datafiles/prvicons.svg21
-rw-r--r--release/datafiles/splash.pngbin254208 -> 187919 bytes
-rw-r--r--release/datafiles/splash_2x.pngbin890649 -> 582704 bytes
m---------release/scripts/addons0
m---------release/scripts/addons_contrib0
-rw-r--r--release/scripts/freestyle/modules/freestyle/__init__.py15
-rw-r--r--release/scripts/freestyle/modules/freestyle/chainingiterators.py138
-rw-r--r--release/scripts/freestyle/modules/freestyle/functions.py105
-rw-r--r--release/scripts/freestyle/modules/freestyle/predicates.py103
-rw-r--r--release/scripts/freestyle/modules/freestyle/shaders.py80
-rw-r--r--release/scripts/freestyle/modules/freestyle/types.py89
-rw-r--r--release/scripts/freestyle/modules/freestyle/utils.py28
-rw-r--r--release/scripts/freestyle/modules/parameter_editor.py19
-rw-r--r--release/scripts/modules/bl_i18n_utils/bl_extract_messages.py4
-rw-r--r--release/scripts/modules/bl_i18n_utils/utils.py2
-rw-r--r--release/scripts/modules/bpy_extras/view3d_utils.py8
-rw-r--r--release/scripts/modules/bpy_types.py2
-rw-r--r--release/scripts/modules/console/complete_namespace.py2
-rw-r--r--release/scripts/modules/rna_xml.py5
-rw-r--r--release/scripts/presets/interface_theme/back_to_black.xml5
-rw-r--r--release/scripts/presets/interface_theme/blender_24x.xml53
-rw-r--r--release/scripts/presets/interface_theme/elsyiun.xml9
-rw-r--r--release/scripts/presets/interface_theme/hexagon.xml9
-rw-r--r--release/scripts/presets/interface_theme/ubuntu_ambiance.xml3
-rw-r--r--release/scripts/startup/bl_operators/__init__.py2
-rw-r--r--release/scripts/startup/bl_operators/anim.py3
-rw-r--r--release/scripts/startup/bl_operators/clip.py4
-rw-r--r--release/scripts/startup/bl_operators/object_quick_effects.py182
-rw-r--r--release/scripts/startup/bl_operators/wm.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_freestyle.py33
-rw-r--r--release/scripts/startup/bl_ui/properties_grease_pencil_common.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_object.py1
-rw-r--r--release/scripts/startup/bl_ui/properties_paint_common.py15
-rw-r--r--release/scripts/startup/bl_ui/space_clip.py2
-rw-r--r--release/scripts/startup/bl_ui/space_image.py5
-rw-r--r--release/scripts/startup/bl_ui/space_node.py2
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py5
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py6
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py21
-rw-r--r--release/scripts/startup/bl_ui/space_view3d_toolbar.py114
-rw-r--r--release/scripts/startup/nodeitems_builtins.py50
-rw-r--r--release/scripts/templates_osl/fresnel_conductive.osl6
-rw-r--r--release/scripts/templates_osl/westin_closure.osl12
-rw-r--r--release/scripts/templates_py/batch_export.py9
-rw-r--r--release/scripts/templates_py/operator_modal_view3d_raycast.py9
-rw-r--r--release/scripts/templates_py/script_stub.py1
-rw-r--r--release/scripts/templates_py/ui_pie_menu.py1
m---------scons0
-rw-r--r--source/blender/avi/intern/avi_rgb.c11
-rw-r--r--source/blender/avi/intern/avi_rgb32.c2
-rw-r--r--source/blender/blenkernel/BKE_animsys.h5
-rw-r--r--source/blender/blenkernel/BKE_blender.h4
-rw-r--r--source/blender/blenkernel/BKE_customdata.h2
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h9
-rw-r--r--source/blender/blenkernel/BKE_library.h4
-rw-r--r--source/blender/blenkernel/BKE_paint.h5
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c4
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c73
-rw-r--r--source/blender/blenkernel/intern/armature.c4
-rw-r--r--source/blender/blenkernel/intern/camera.c2
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c69
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/collision.c2
-rw-r--r--source/blender/blenkernel/intern/colortools.c4
-rw-r--r--source/blender/blenkernel/intern/constraint.c2
-rw-r--r--source/blender/blenkernel/intern/curve.c17
-rw-r--r--source/blender/blenkernel/intern/customdata.c8
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c2
-rw-r--r--source/blender/blenkernel/intern/effect.c2
-rw-r--r--source/blender/blenkernel/intern/fcurve.c45
-rw-r--r--source/blender/blenkernel/intern/image.c10
-rw-r--r--source/blender/blenkernel/intern/implicit.c2
-rw-r--r--source/blender/blenkernel/intern/lamp.c3
-rw-r--r--source/blender/blenkernel/intern/library.c2
-rw-r--r--source/blender/blenkernel/intern/linestyle.c2
-rw-r--r--source/blender/blenkernel/intern/mask.c6
-rw-r--r--source/blender/blenkernel/intern/movieclip.c21
-rw-r--r--source/blender/blenkernel/intern/node.c10
-rw-r--r--source/blender/blenkernel/intern/object.c10
-rw-r--r--source/blender/blenkernel/intern/paint.c25
-rw-r--r--source/blender/blenkernel/intern/particle.c53
-rw-r--r--source/blender/blenkernel/intern/particle_system.c2
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c33
-rw-r--r--source/blender/blenkernel/intern/pointcache.c7
-rw-r--r--source/blender/blenkernel/intern/scene.c9
-rw-r--r--source/blender/blenkernel/intern/seqcache.c87
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c6
-rw-r--r--source/blender/blenkernel/intern/softbody.c6
-rw-r--r--source/blender/blenkernel/intern/text.c271
-rw-r--r--source/blender/blenkernel/intern/tracking.c83
-rw-r--r--source/blender/blenkernel/intern/treehash.c2
-rw-r--r--source/blender/blenlib/BLI_array.h24
-rw-r--r--source/blender/blenlib/BLI_compiler_typecheck.h379
-rw-r--r--source/blender/blenlib/BLI_ghash.h12
-rw-r--r--source/blender/blenlib/BLI_kdopbvh.h2
-rw-r--r--source/blender/blenlib/BLI_listbase.h4
-rw-r--r--source/blender/blenlib/BLI_math_base.h6
-rw-r--r--source/blender/blenlib/BLI_math_color_blend.h32
-rw-r--r--source/blender/blenlib/BLI_stack.h3
-rw-r--r--source/blender/blenlib/BLI_stackdefines.h7
-rw-r--r--source/blender/blenlib/BLI_strict_flags.h6
-rw-r--r--source/blender/blenlib/BLI_utildefines.h53
-rw-r--r--source/blender/blenlib/CMakeLists.txt1
-rw-r--r--source/blender/blenlib/intern/BLI_args.c12
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c34
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c2
-rw-r--r--source/blender/blenlib/intern/buffer.c18
-rw-r--r--source/blender/blenlib/intern/listbase.c4
-rw-r--r--source/blender/blenlib/intern/math_color_blend_inline.c32
-rw-r--r--source/blender/blenlib/intern/math_geom.c13
-rw-r--r--source/blender/blenlib/intern/math_rotation.c4
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c12
-rw-r--r--source/blender/blenlib/intern/path_util.c7
-rw-r--r--source/blender/blenlib/intern/polyfill2d.c2
-rw-r--r--source/blender/blenlib/intern/scanfill_utils.c6
-rw-r--r--source/blender/blenlib/intern/stack.c42
-rw-r--r--source/blender/blenloader/intern/readfile.c6
-rw-r--r--source/blender/blenloader/intern/versioning_250.c3
-rw-r--r--source/blender/blenloader/intern/versioning_270.c41
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c1
-rw-r--r--source/blender/bmesh/CMakeLists.txt2
-rw-r--r--source/blender/bmesh/bmesh.h4
-rw-r--r--source/blender/bmesh/bmesh_tools.h1
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c8
-rw-r--r--source/blender/bmesh/intern/bmesh_core.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_interp.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.c42
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.h27
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators_inline.h18
-rw-r--r--source/blender/bmesh/intern/bmesh_marking.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_mods.c5
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c1
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c54
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.c25
-rw-r--r--source/blender/bmesh/intern/bmesh_structure.h1
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide.c63
-rw-r--r--source/blender/bmesh/operators/bmo_utils.c3
-rw-r--r--source/blender/bmesh/tools/bmesh_bisect_plane.c25
-rw-r--r--source/blender/bmesh/tools/bmesh_region_match.c1511
-rw-r--r--source/blender/bmesh/tools/bmesh_region_match.h33
-rw-r--r--source/blender/collada/collada.cpp20
-rw-r--r--source/blender/compositor/nodes/COM_BlurNode.cpp2
-rw-r--r--source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp27
-rw-r--r--source/blender/compositor/operations/COM_GaussianXBlurOperation.h11
-rw-r--r--source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp27
-rw-r--r--source/blender/compositor/operations/COM_GaussianYBlurOperation.h11
-rw-r--r--source/blender/compositor/operations/COM_KeyingBlurOperation.cpp38
-rw-r--r--source/blender/compositor/operations/COM_KeyingScreenOperation.cpp21
-rw-r--r--source/blender/compositor/operations/COM_KeyingScreenOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_MapUVOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_MixOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_OpenCLKernels.cl63
-rw-r--r--source/blender/compositor/operations/COM_SunBeamsOperation.cpp32
-rw-r--r--source/blender/editors/animation/drivers.c76
-rw-r--r--source/blender/editors/armature/armature_edit.c6
-rw-r--r--source/blender/editors/armature/armature_intern.h2
-rw-r--r--source/blender/editors/armature/armature_relations.c2
-rw-r--r--source/blender/editors/armature/armature_select.c33
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c4
-rw-r--r--source/blender/editors/armature/pose_select.c4
-rw-r--r--source/blender/editors/curve/editfont.c14
-rw-r--r--source/blender/editors/include/ED_armature.h2
-rw-r--r--source/blender/editors/include/ED_image.h2
-rw-r--r--source/blender/editors/include/ED_render.h13
-rw-r--r--source/blender/editors/include/UI_interface.h1
-rw-r--r--source/blender/editors/interface/interface_anim.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c26
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c2
-rw-r--r--source/blender/editors/interface/interface_templates.c3
-rw-r--r--source/blender/editors/interface/interface_widgets.c19
-rw-r--r--source/blender/editors/io/io_collada.c61
-rw-r--r--source/blender/editors/mask/mask_edit.c2
-rw-r--r--source/blender/editors/mask/mask_ops.c13
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c8
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c202
-rw-r--r--source/blender/editors/mesh/editmesh_rip.c6
-rw-r--r--source/blender/editors/mesh/editmesh_select.c92
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c14
-rw-r--r--source/blender/editors/mesh/mesh_data.c13
-rw-r--r--source/blender/editors/mesh/mesh_intern.h1
-rw-r--r--source/blender/editors/mesh/mesh_ops.c3
-rw-r--r--source/blender/editors/mesh/meshtools.c2
-rw-r--r--source/blender/editors/object/object_bake.c1
-rw-r--r--source/blender/editors/object/object_bake_api.c6
-rw-r--r--source/blender/editors/object/object_relations.c7
-rw-r--r--source/blender/editors/object/object_transform.c2
-rw-r--r--source/blender/editors/object/object_vgroup.c6
-rw-r--r--source/blender/editors/physics/particle_edit.c8
-rw-r--r--source/blender/editors/physics/physics_fluid.c4
-rw-r--r--source/blender/editors/render/render_preview.c15
-rw-r--r--source/blender/editors/render/render_shading.c19
-rw-r--r--source/blender/editors/render/render_update.c19
-rw-r--r--source/blender/editors/sculpt_paint/paint_cursor.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c61
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c294
-rw-r--r--source/blender/editors/sculpt_paint/paint_intern.h2
-rw-r--r--source/blender/editors/sculpt_paint/paint_mask.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_ops.c9
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c8
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c26
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_uv.c18
-rw-r--r--source/blender/editors/space_clip/space_clip.c4
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c2
-rw-r--r--source/blender/editors/space_file/fsmenu.c2
-rw-r--r--source/blender/editors/space_image/image_buttons.c4
-rw-r--r--source/blender/editors/space_image/image_edit.c25
-rw-r--r--source/blender/editors/space_image/image_ops.c60
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_node/node_relationships.c10
-rw-r--r--source/blender/editors/space_node/node_select.c38
-rw-r--r--source/blender/editors/space_node/space_node.c2
-rw-r--r--source/blender/editors/space_text/text_draw.c16
-rw-r--r--source/blender/editors/space_text/text_ops.c4
-rw-r--r--source/blender/editors/space_time/space_time.c1
-rw-r--r--source/blender/editors/space_view3d/drawmesh.c14
-rw-r--r--source/blender/editors/space_view3d/drawobject.c5
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c148
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c2
-rw-r--r--source/blender/editors/transform/transform.c8
-rw-r--r--source/blender/editors/transform/transform.h1
-rw-r--r--source/blender/editors/transform/transform_conversions.c16
-rw-r--r--source/blender/editors/transform/transform_manipulator.c2
-rw-r--r--source/blender/editors/transform/transform_snap.c12
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c22
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c28
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c2
-rw-r--r--source/blender/freestyle/CMakeLists.txt2
-rw-r--r--source/blender/freestyle/FRS_freestyle.h1
-rw-r--r--source/blender/freestyle/intern/application/Controller.cpp91
-rw-r--r--source/blender/freestyle/intern/application/Controller.h11
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp15
-rw-r--r--source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp14
-rw-r--r--source/blender/freestyle/intern/python/BPy_Interface0D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BPy_Operators.cpp35
-rw-r--r--source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp4
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp8
-rw-r--r--source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp4
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp13
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp6
-rw-r--r--source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp7
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.cpp6
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp19
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp26
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp10
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp10
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp12
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp12
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp10
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp12
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp10
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp11
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp11
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp14
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp10
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp8
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp20
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp10
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp21
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp12
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp15
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp19
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp11
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp11
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp16
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp12
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp6
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp9
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp8
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp4
-rw-r--r--source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp2
-rw-r--r--source/blender/freestyle/intern/scene_graph/SceneHash.cpp39
-rw-r--r--source/blender/freestyle/intern/scene_graph/SceneHash.h67
-rw-r--r--source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp5
-rw-r--r--source/blender/freestyle/intern/stroke/Chain.cpp2
-rw-r--r--source/blender/freestyle/intern/stroke/Chain.h4
-rw-r--r--source/blender/freestyle/intern/stroke/Curve.h8
-rw-r--r--source/blender/freestyle/intern/stroke/Operators.cpp12
-rw-r--r--source/blender/freestyle/intern/stroke/Operators.h2
-rw-r--r--source/blender/freestyle/intern/stroke/Stroke.h8
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp24
-rw-r--r--source/blender/freestyle/intern/view_map/FEdgeXDetector.h4
-rw-r--r--source/blender/freestyle/intern/view_map/Silhouette.h42
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.cpp24
-rw-r--r--source/blender/freestyle/intern/view_map/ViewMap.h7
-rw-r--r--source/blender/freestyle/intern/winged_edge/WXEdge.h14
-rw-r--r--source/blender/gpu/intern/gpu_extensions.c9
-rw-r--r--source/blender/gpu/intern/gpu_material.c16
-rw-r--r--source/blender/gpu/intern/gpu_select.c2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl5
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp2
-rw-r--r--source/blender/imbuf/intern/cache.c16
-rw-r--r--source/blender/imbuf/intern/colormanagement.c15
-rw-r--r--source/blender/imbuf/intern/moviecache.c2
-rw-r--r--source/blender/imbuf/intern/readimage.c2
-rw-r--r--source/blender/makesdna/DNA_ID.h14
-rw-r--r--source/blender/makesdna/DNA_brush_types.h2
-rw-r--r--source/blender/makesdna/DNA_freestyle_types.h1
-rw-r--r--source/blender/makesdna/DNA_image_types.h1
-rw-r--r--source/blender/makesdna/DNA_lamp_types.h36
-rw-r--r--source/blender/makesdna/DNA_linestyle_types.h6
-rw-r--r--source/blender/makesdna/DNA_scene_types.h8
-rw-r--r--source/blender/makesdna/DNA_space_types.h1
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h7
-rw-r--r--source/blender/makesdna/DNA_view3d_types.h2
-rw-r--r--source/blender/makesrna/SConscript7
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt6
-rw-r--r--source/blender/makesrna/intern/SConscript3
-rw-r--r--source/blender/makesrna/intern/rna_ID.c3
-rw-r--r--source/blender/makesrna/intern/rna_brush.c4
-rw-r--r--source/blender/makesrna/intern/rna_image.c7
-rw-r--r--source/blender/makesrna/intern/rna_image_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_linestyle.c12
-rw-r--r--source/blender/makesrna/intern/rna_material.c4
-rw-r--r--source/blender/makesrna/intern/rna_object.c2
-rw-r--r--source/blender/makesrna/intern/rna_render.c17
-rw-r--r--source/blender/makesrna/intern/rna_scene.c34
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c64
-rw-r--r--source/blender/makesrna/intern/rna_smoke.c2
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c22
-rw-r--r--source/blender/modifiers/CMakeLists.txt4
-rw-r--r--source/blender/modifiers/SConscript3
-rw-r--r--source/blender/modifiers/intern/MOD_array.c69
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c6
-rw-r--r--source/blender/modifiers/intern/MOD_wireframe.c9
-rw-r--r--source/blender/nodes/intern/node_exec.c5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_camera.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_math.c22
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_vectMath.c4
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c2
-rw-r--r--source/blender/nodes/texture/node_texture_util.c18
-rw-r--r--source/blender/nodes/texture/nodes/node_texture_math.c12
-rw-r--r--source/blender/python/bmesh/bmesh_py_ops_call.c2
-rw-r--r--source/blender/python/intern/bpy_app_translations.c7
-rw-r--r--source/blender/python/intern/bpy_interface.c2
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c2
-rw-r--r--source/blender/python/rna_dump.py38
-rw-r--r--source/blender/render/CMakeLists.txt4
-rw-r--r--source/blender/render/SConscript3
-rw-r--r--source/blender/render/extern/include/RE_engine.h1
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h5
-rw-r--r--source/blender/render/intern/raytrace/rayobject_octree.cpp2
-rw-r--r--source/blender/render/intern/source/convertblender.c16
-rw-r--r--source/blender/render/intern/source/initrender.c2
-rw-r--r--source/blender/render/intern/source/multires_bake.c8
-rw-r--r--source/blender/render/intern/source/pipeline.c60
-rw-r--r--source/blender/render/intern/source/pixelshading.c24
-rw-r--r--source/blender/render/intern/source/pointdensity.c2
-rw-r--r--source/blender/render/intern/source/rayshade.c24
-rw-r--r--source/blender/render/intern/source/render_result.c38
-rw-r--r--source/blender/render/intern/source/render_texture.c49
-rw-r--r--source/blender/render/intern/source/rendercore.c4
-rw-r--r--source/blender/render/intern/source/renderdatabase.c16
-rw-r--r--source/blender/render/intern/source/shadbuf.c8
-rw-r--r--source/blender/render/intern/source/shadeoutput.c30
-rw-r--r--source/blender/render/intern/source/sss.c10
-rw-r--r--source/blender/render/intern/source/strand.c2
-rw-r--r--source/blender/render/intern/source/sunsky.c6
-rw-r--r--source/blender/render/intern/source/zbuf.c6
-rw-r--r--source/blender/windowmanager/intern/wm_keymap.c6
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c24
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c61
-rw-r--r--source/blender/windowmanager/intern/wm_window.c19
-rw-r--r--source/blender/windowmanager/wm_window.h2
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c6
-rw-r--r--source/creator/CMakeLists.txt5
-rw-r--r--source/creator/creator.c27
-rw-r--r--source/creator/creator_launch_win.c7
-rw-r--r--source/creator/osx_locals.map3
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp7
-rw-r--r--source/gameengine/Converter/BL_ArmatureObject.cpp2
-rw-r--r--source/gameengine/Ketsji/KX_KetsjiEngine.cpp52
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp7
-rw-r--r--tests/gtests/blenlib/BLI_polyfill2d_test.cc492
-rw-r--r--tests/gtests/blenlib/BLI_stack_test.cc23
-rw-r--r--tests/gtests/blenlib/CMakeLists.txt1
-rw-r--r--tests/python/bl_mesh_modifiers.py2
-rw-r--r--tests/python/rna_array.py2
698 files changed, 21613 insertions, 11549 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 677150efd88..1fb406f650f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -252,6 +252,7 @@ option(WITH_LZMA "Enable best LZMA compression, (used for pointcache)"
# Camera/motion tracking
option(WITH_LIBMV "Enable libmv structure from motion library" ON)
+option(WITH_LIBMV_SCHUR_SPECIALIZATIONS "Enable fixed-size schur specializations." ON)
# Freestyle
option(WITH_FREESTYLE "Enable Freestyle (advanced edges rendering)" ON)
@@ -288,6 +289,10 @@ option(WITH_CYCLES_CUDA_BINARIES "Build cycles CUDA binaries" OFF)
set(CYCLES_CUDA_BINARIES_ARCH sm_20 sm_21 sm_30 sm_35 sm_50 CACHE STRING "CUDA architectures to build binaries for")
mark_as_advanced(CYCLES_CUDA_BINARIES_ARCH)
unset(PLATFORM_DEFAULT)
+option(WITH_CYCLES_LOGGING "Build cycles with logging support" OFF)
+option(WITH_CYCLES_DEBUG "Build cycles with with extra debug capabilties" OFF)
+mark_as_advanced(WITH_CYCLES_LOGGING)
+mark_as_advanced(WITH_CYCLES_DEBUG)
# LLVM
option(WITH_LLVM "Use LLVM" OFF)
@@ -374,6 +379,8 @@ if(APPLE)
execute_process(COMMAND uname -r OUTPUT_VARIABLE MAC_SYS) # check for actual system-version
if(${MAC_SYS} MATCHES 14)
set(OSX_SYSTEM 10.10)
+ # throw an error here, older cmake cannot handle 2 digit subversion!
+ cmake_minimum_required(VERSION 3.0.0)
elseif(${MAC_SYS} MATCHES 13)
set(OSX_SYSTEM 10.9)
elseif(${MAC_SYS} MATCHES 12)
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index c1b2fd96c97..a5acbe9b612 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -25,10 +25,12 @@
ARGS=$( \
getopt \
-o s:i:t:h \
---long source:,install:,tmp:,threads:,help,no-sudo,with-all,with-opencollada,ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,\
+--long source:,install:,tmp:,info:,threads:,help,no-sudo,with-all,with-opencollada,\
+ver-ocio:,ver-oiio:,ver-llvm:,ver-osl:,\
force-all,force-python,force-numpy,force-boost,force-ocio,force-oiio,force-llvm,force-osl,force-opencollada,\
-force-ffmpeg,skip-python,skip-numpy,skip-boost,skip-ocio,skip-oiio,skip-llvm,skip-osl,skip-ffmpeg,\
-skip-opencollada,required-numpy: \
+force-ffmpeg,\
+skip-python,skip-numpy,skip-boost,skip-ocio,skip-openexr,skip-oiio,skip-llvm,skip-osl,skip-ffmpeg,skip-opencollada,\
+required-numpy: \
-- "$@" \
)
@@ -38,6 +40,7 @@ SRC="$HOME/src/blender-deps"
INST="/opt/lib"
TMP="/tmp"
CWD=$PWD
+INFO_PATH=$CWD
# Do not install some optional, potentially conflicting libs by default...
WITH_ALL=false
@@ -74,6 +77,9 @@ ARGUMENTS_INFO="\"COMMAND LINE ARGUMENTS:
--tmp=<path>
Use a specific temp path (defaults to '\$TMP').
+ --info=<path>
+ Use a specific info path (to store BUILD_NOTES.txt, defaults to '\$INFO_PATH').
+
-t n, --threads=n
Use a specific number of threads when building the libraries (auto-detected as '\$THREADS').
@@ -320,6 +326,9 @@ while true; do
--tmp)
TMP="$2"; shift; shift; continue
;;
+ --info)
+ INFO_PATH="$2"; shift; shift; continue
+ ;;
-t|--threads)
THREADS="$2"; shift; shift; continue
;;
@@ -3098,9 +3107,9 @@ else
exit 1
fi
-print_info | tee BUILD_NOTES.txt
+print_info | tee $INFO_PATH/BUILD_NOTES.txt
PRINT ""
-PRINT "This information has been written to BUILD_NOTES.txt"
+PRINT "This information has been written to $INFO_PATH/BUILD_NOTES.txt"
PRINT ""
# Switch back to user language.
diff --git a/build_files/buildbot/config/user-config-glibc211-i686.py b/build_files/buildbot/config/user-config-glibc211-i686.py
index d7a1439e003..0971735f641 100644
--- a/build_files/buildbot/config/user-config-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-glibc211-i686.py
@@ -49,7 +49,7 @@ BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.7.1/libstdc++.a'
WITH_BF_OPENAL = True
WITH_BF_STATICOPENAL = True
BF_OPENAL = '/opt/lib/openal'
-BF_OPENAL_LIB_STATIC = '/opt/lib/openal/lib/libopenal.a'
+BF_OPENAL_LIB_STATIC = '/opt/lib/openal/lib/libopenal.a /opt/lib/openal/lib/libcommon.a'
WITH_BF_GETTEXT_STATIC = True
diff --git a/build_files/buildbot/config/user-config-glibc211-x86_64.py b/build_files/buildbot/config/user-config-glibc211-x86_64.py
index f07c447bf29..748d1004850 100644
--- a/build_files/buildbot/config/user-config-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-glibc211-x86_64.py
@@ -49,7 +49,7 @@ BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.7.1/libstdc++.a'
WITH_BF_OPENAL = True
WITH_BF_STATICOPENAL = True
BF_OPENAL = '/opt/lib/openal'
-BF_OPENAL_LIB_STATIC = '/opt/lib/openal/lib/libopenal.a'
+BF_OPENAL_LIB_STATIC = '/opt/lib/openal/lib/libopenal.a /opt/lib/openal/lib/libcommon.a'
WITH_BF_GETTEXT_STATIC = True
diff --git a/build_files/buildbot/config/user-config-player-glibc211-i686.py b/build_files/buildbot/config/user-config-player-glibc211-i686.py
index 641dbe082ad..384da4070eb 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-i686.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-i686.py
@@ -34,7 +34,7 @@ BF_CXX_LIB_STATIC = '/usr/lib/gcc/i486-linux-gnu/4.7.1/libstdc++.a'
WITH_BF_OPENAL = True
WITH_BF_STATICOPENAL = True
BF_OPENAL = '/opt/lib/openal'
-BF_OPENAL_LIB_STATIC = '/opt/lib/openal/lib/libopenal.a'
+BF_OPENAL_LIB_STATIC = '/opt/lib/openal/lib/libopenal.a /opt/lib/openal/lib/libcommon.a'
WITH_BF_GETTEXT_STATIC = True
diff --git a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
index 80503268b44..5176d59d5a0 100644
--- a/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
+++ b/build_files/buildbot/config/user-config-player-glibc211-x86_64.py
@@ -34,7 +34,7 @@ BF_CXX_LIB_STATIC = '/usr/lib/gcc/x86_64-linux-gnu/4.7.1/libstdc++.a'
WITH_BF_OPENAL = True
WITH_BF_STATICOPENAL = True
BF_OPENAL = '/opt/lib/openal'
-BF_OPENAL_LIB_STATIC = '/opt/lib/openal/lib/libopenal.a'
+BF_OPENAL_LIB_STATIC = '/opt/lib/openal/lib/libopenal.a /opt/lib/openal/lib/libcommon.a'
WITH_BF_GETTEXT_STATIC = True
diff --git a/build_files/cmake/cmake_consistency_check.py b/build_files/cmake/cmake_consistency_check.py
index c2044fcc21d..2e0eeb1e067 100755
--- a/build_files/cmake/cmake_consistency_check.py
+++ b/build_files/cmake/cmake_consistency_check.py
@@ -174,7 +174,7 @@ def cmake_get_src(f):
elif is_c(new_file):
sources_c.append(new_file)
global_refs.setdefault(new_file, []).append((f, i))
- elif l in ("PARENT_SCOPE", ):
+ elif l in {"PARENT_SCOPE", }:
# cmake var, ignore
pass
elif new_file.endswith(".list"):
diff --git a/build_files/scons/tools/btools.py b/build_files/scons/tools/btools.py
index b7bd27dea03..12cbbb1618a 100644
--- a/build_files/scons/tools/btools.py
+++ b/build_files/scons/tools/btools.py
@@ -178,7 +178,7 @@ def validate_arguments(args, bc):
'WITH_BF_OIIO', 'WITH_BF_STATICOIIO', 'BF_OIIO', 'BF_OIIO_INC', 'BF_OIIO_LIB', 'BF_OIIO_LIB_STATIC', 'BF_OIIO_LIBPATH',
'WITH_BF_OCIO', 'WITH_BF_STATICOCIO', 'BF_OCIO', 'BF_OCIO_INC', 'BF_OCIO_LIB', 'BF_OCIO_LIB_STATIC', 'BF_OCIO_LIBPATH',
'WITH_BF_BOOST', 'WITH_BF_STATICBOOST', 'BF_BOOST', 'BF_BOOST_INC', 'BF_BOOST_LIB', 'BF_BOOST_LIB_INTERNATIONAL', 'BF_BOOST_LIB_STATIC', 'BF_BOOST_LIBPATH',
- 'WITH_BF_LIBMV',
+ 'WITH_BF_LIBMV', 'WITH_BF_LIBMV_SCHUR_SPECIALIZATIONS',
'WITH_BF_CYCLES_OSL', 'WITH_BF_STATICOSL', 'BF_OSL', 'BF_OSL_INC', 'BF_OSL_LIB', 'BF_OSL_LIBPATH', 'BF_OSL_LIB_STATIC', 'BF_OSL_COMPILER',
'WITH_BF_LLVM', 'WITH_BF_STATICLLVM', 'BF_LLVM', 'BF_LLVM_LIB', 'BF_LLVM_LIBPATH', 'BF_LLVM_LIB_STATIC', 'BF_PROGRAM_LINKFLAGS'
]
@@ -195,7 +195,8 @@ def validate_arguments(args, bc):
'BF_DEBUG_CFLAGS', 'BF_DEBUG_CCFLAGS', 'BF_DEBUG_CXXFLAGS',
'C_WARN', 'CC_WARN', 'CXX_WARN',
'LLIBS', 'PLATFORM_LINKFLAGS', 'MACOSX_ARCHITECTURE', 'MACOSX_SDK', 'XCODE_CUR_VER', 'C_COMPILER_ID',
- 'BF_CYCLES_CUDA_BINARIES_ARCH', 'BF_PROGRAM_LINKFLAGS', 'MACOSX_DEPLOYMENT_TARGET'
+ 'BF_CYCLES_CUDA_BINARIES_ARCH', 'BF_PROGRAM_LINKFLAGS', 'MACOSX_DEPLOYMENT_TARGET',
+ 'WITH_BF_CYCLES_DEBUG'
]
@@ -571,6 +572,7 @@ def read_opts(env, cfg, args):
(BoolVariable('WITH_BF_LZMA', 'Enable best LZMA pointcache compression', True)),
(BoolVariable('WITH_BF_LIBMV', 'Enable libmv structure from motion library', True)),
+ (BoolVariable('WITH_BF_LIBMV_SCHUR_SPECIALIZATIONS', 'Enable fixed-size schur specializations', True)),
(BoolVariable('WITH_BF_COMPOSITOR', 'Enable the tile based nodal compositor', True)),
) # end of opts.AddOptions()
@@ -600,6 +602,7 @@ def read_opts(env, cfg, args):
('BF_CYCLES_CUDA_NVCC', 'CUDA nvcc compiler path', ''),
('BF_CYCLES_CUDA_ENV', 'preset environement nvcc will execute in', ''),
('BF_CYCLES_CUDA_BINARIES_ARCH', 'CUDA architectures to compile binaries for', []),
+ (BoolVariable('WITH_BF_CYCLES_DEBUG', 'Build Cycles engine with extra debugging capabilities', False)),
(BoolVariable('WITH_BF_OIIO', 'Build with OpenImageIO', False)),
(BoolVariable('WITH_BF_STATICOIIO', 'Statically link to OpenImageIO', False)),
diff --git a/build_files/utils/build_tgz.sh b/build_files/utils/build_tgz.sh
index b0ff8ea2aa8..409c738e9f8 100755
--- a/build_files/utils/build_tgz.sh
+++ b/build_files/utils/build_tgz.sh
@@ -22,15 +22,18 @@ TARBALL="blender-$VERSION.tar.gz"
cd "$blender_srcdir"
+# not so nice, but works
+FILTER_FILES_PY="import os, sys; [print(l[:-1]) for l in sys.stdin.readlines() if os.path.isfile(l[:-1])]"
+
# Build master list
echo -n "Building manifest of files: \"$BASE_DIR/$MANIFEST\" ..."
-git ls-files > $BASE_DIR/$MANIFEST
+git ls-files | python3 -c "$FILTER_FILES_PY" > $BASE_DIR/$MANIFEST
# Enumerate submodules
-for lcv in $(git submodule | cut -f2 -d" "); do
+for lcv in $(git submodule | awk '{print $2}'); do
cd "$BASE_DIR"
cd "$blender_srcdir/$lcv"
- git ls-files | awk '$0="'"$lcv"/'"$0' >> $BASE_DIR/$MANIFEST
+ git ls-files | python3 -c "$FILTER_FILES_PY" | awk '$0="'"$lcv"/'"$0' >> $BASE_DIR/$MANIFEST
cd "$BASE_DIR"
done
echo "OK"
diff --git a/doc/python_api/examples/bpy.props.5.py b/doc/python_api/examples/bpy.props.5.py
index d2ace54de27..4e9d61d5385 100644
--- a/doc/python_api/examples/bpy.props.5.py
+++ b/doc/python_api/examples/bpy.props.5.py
@@ -75,7 +75,7 @@ print(scene.test_float)
scene.test_array = (True, False)
print([x for x in scene.test_array])
-#scene.test_date = "blah" # this would fail, property is read-only
+# scene.test_date = "blah" # this would fail, property is read-only
print(scene.test_date)
scene.test_enum = 'BLUE'
diff --git a/doc/python_api/examples/bpy.types.Operator.5.py b/doc/python_api/examples/bpy.types.Operator.5.py
index 4a0abcb62c3..78030c7d7c4 100644
--- a/doc/python_api/examples/bpy.types.Operator.5.py
+++ b/doc/python_api/examples/bpy.types.Operator.5.py
@@ -39,7 +39,7 @@ class ModalOperator(bpy.types.Operator):
self.execute(context)
elif event.type == 'LEFTMOUSE': # Confirm
return {'FINISHED'}
- elif event.type in ('RIGHTMOUSE', 'ESC'): # Cancel
+ elif event.type in {'RIGHTMOUSE', 'ESC'}: # Cancel
context.object.location.x = self.init_loc_x
return {'CANCELLED'}
diff --git a/doc/python_api/examples/bpy.types.bpy_prop_collection.foreach_get.py b/doc/python_api/examples/bpy.types.bpy_prop_collection.foreach_get.py
index 05163b332a9..a83b23e84f9 100644
--- a/doc/python_api/examples/bpy.types.bpy_prop_collection.foreach_get.py
+++ b/doc/python_api/examples/bpy.types.bpy_prop_collection.foreach_get.py
@@ -8,4 +8,3 @@ collection.foreach_get(attr, some_seq)
# Python equivalent
for i in range(len(seq)):
some_seq[i] = getattr(collection[i], attr)
-
diff --git a/doc/python_api/sphinx_doc_gen.py b/doc/python_api/sphinx_doc_gen.py
index 98bf6bf2eed..0b9a4e6a37b 100644
--- a/doc/python_api/sphinx_doc_gen.py
+++ b/doc/python_api/sphinx_doc_gen.py
@@ -1,22 +1,22 @@
- # ***** BEGIN GPL LICENSE BLOCK *****
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License
- # as published by the Free Software Foundation; either version 2
- # of the License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software Foundation,
- # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- #
- # Contributor(s): Campbell Barton, Luca Bonavita
- #
- # #**** END GPL LICENSE BLOCK #****
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributor(s): Campbell Barton
+#
+# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
@@ -274,6 +274,12 @@ else:
"mathutils.kdtree",
"mathutils.noise",
"freestyle",
+ "freestyle.chainingiterators",
+ "freestyle.functions",
+ "freestyle.predicates",
+ "freestyle.shaders",
+ "freestyle.types",
+ "freestyle.utils",
]
# ------
@@ -316,7 +322,13 @@ try:
__import__("freestyle")
except ImportError:
BPY_LOGGER.debug("Warning: Built without 'freestyle' module, docs incomplete...")
- EXCLUDE_MODULES = list(EXCLUDE_MODULES) + ["freestyle"]
+ EXCLUDE_MODULES = list(EXCLUDE_MODULES) + ["freestyle",
+ "freestyle.chainingiterators",
+ "freestyle.functions",
+ "freestyle.predicates",
+ "freestyle.shaders",
+ "freestyle.types",
+ "freestyle.utils"]
# examples
EXAMPLES_DIR = os.path.abspath(os.path.join(SCRIPT_DIR, "examples"))
@@ -683,7 +695,7 @@ def py_descr2sphinx(ident, fw, descr, module_name, type_name, identifier):
fw(ident + ".. data:: %s\n\n" % identifier)
write_indented_lines(ident + " ", fw, doc, False)
fw("\n")
- elif type(descr) in (MethodDescriptorType, ClassMethodDescriptorType):
+ elif type(descr) in {MethodDescriptorType, ClassMethodDescriptorType}:
write_indented_lines(ident, fw, doc, False)
fw("\n")
else:
@@ -877,7 +889,7 @@ def pymodule2sphinx(basepath, module_name, module, title):
for attribute, value, value_type in module_dir_value_type:
if value_type == types.FunctionType:
pyfunc2sphinx("", fw, module_name, None, attribute, value, is_class=False)
- elif value_type in (types.BuiltinMethodType, types.BuiltinFunctionType): # both the same at the moment but to be future proof
+ elif value_type in {types.BuiltinMethodType, types.BuiltinFunctionType}: # both the same at the moment but to be future proof
# note: can't get args from these, so dump the string as is
# this means any module used like this must have fully formatted docstrings.
py_c_func2sphinx("", fw, module_name, None, attribute, value, is_class=False)
@@ -1780,8 +1792,14 @@ def write_rst_importable_modules(basepath):
"mathutils.geometry" : "Geometry Utilities",
"mathutils.kdtree" : "KDTree Utilities",
"mathutils.noise" : "Noise Utilities",
- "freestyle" : "Freestyle Data Types & Operators",
- }
+ "freestyle" : "Freestyle Module",
+ "freestyle.types" : "Freestyle Types",
+ "freestyle.predicates" : "Freestyle Predicates",
+ "freestyle.functions" : "Freestyle Functions",
+ "freestyle.chainingiterators" : "Freestyle Chaining Iterators",
+ "freestyle.shaders" : "Freestyle Shaders",
+ "freestyle.utils" : "Freestyle Utilities",
+ }
for mod_name, mod_descr in importable_modules.items():
if mod_name not in EXCLUDE_MODULES:
module = __import__(mod_name,
@@ -1852,8 +1870,8 @@ def rna2sphinx(basepath):
# context
if "bpy.context" not in EXCLUDE_MODULES:
# one of a kind, context doc (uses ctypes to extract info!)
- # doesn't work on mac
- if PLATFORM != "darwin":
+ # doesn't work on mac and windows
+ if PLATFORM not in {"darwin", "windows"}:
pycontext2sphinx(basepath)
# internal modules
diff --git a/doc/python_api/sphinx_doc_gen.sh b/doc/python_api/sphinx_doc_gen.sh
index c8256a1c4cd..d7fc372a8d8 100755
--- a/doc/python_api/sphinx_doc_gen.sh
+++ b/doc/python_api/sphinx_doc_gen.sh
@@ -100,7 +100,7 @@ if $DO_UPLOAD ; then
cp $SPHINXBASE/sphinx-out/contents.html $SPHINXBASE/sphinx-out/index.html
ssh $SSH_USER@blender.org 'rm -rf '$SSH_UPLOAD_FULL'/*'
- rsync --progress -avze "ssh -p 22" $SPHINXBASE/sphinx-out/* $SSH_HOST:$SSH_UPLOAD_FULL/
+ rsync --progress -ave "ssh -p 22" $SPHINXBASE/sphinx-out/* $SSH_HOST:$SSH_UPLOAD_FULL/
## symlink the dir to a static URL
#ssh $SSH_USER@blender.org 'rm '$SSH_UPLOAD'/250PythonDoc && ln -s '$SSH_UPLOAD_FULL' '$SSH_UPLOAD'/250PythonDoc'
@@ -115,11 +115,11 @@ if $DO_UPLOAD ; then
if $DO_OUT_PDF ; then
# rename so local PDF has matching name.
- rsync --progress -avze "ssh -p 22" $SPHINXBASE/sphinx-out/blender_python_reference_$BLENDER_VERSION.pdf $SSH_HOST:$SSH_UPLOAD_FULL/blender_python_reference_$BLENDER_VERSION.pdf
+ rsync --progress -ave "ssh -p 22" $SPHINXBASE/sphinx-out/blender_python_reference_$BLENDER_VERSION.pdf $SSH_HOST:$SSH_UPLOAD_FULL/blender_python_reference_$BLENDER_VERSION.pdf
fi
if $DO_OUT_HTML_ZIP ; then
- rsync --progress -avze "ssh -p 22" $SPHINXBASE/blender_python_reference_$BLENDER_VERSION.zip $SSH_HOST:$SSH_UPLOAD_FULL/blender_python_reference_$BLENDER_VERSION.zip
+ rsync --progress -ave "ssh -p 22" $SPHINXBASE/blender_python_reference_$BLENDER_VERSION.zip $SSH_HOST:$SSH_UPLOAD_FULL/blender_python_reference_$BLENDER_VERSION.zip
fi
fi
diff --git a/doc/python_api/sphinx_doc_gen_monkeypatch.py b/doc/python_api/sphinx_doc_gen_monkeypatch.py
index 1167ece05b7..9fdbf613d96 100644
--- a/doc/python_api/sphinx_doc_gen_monkeypatch.py
+++ b/doc/python_api/sphinx_doc_gen_monkeypatch.py
@@ -1,22 +1,22 @@
- # ***** BEGIN GPL LICENSE BLOCK *****
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License
- # as published by the Free Software Foundation; either version 2
- # of the License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software Foundation,
- # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- #
- # Contributor(s): Campbell Barton
- #
- # #**** END GPL LICENSE BLOCK #****
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributor(s): Campbell Barton
+#
+# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt
index 9030ae9c1ed..09c36fc4383 100644
--- a/extern/libmv/CMakeLists.txt
+++ b/extern/libmv/CMakeLists.txt
@@ -35,12 +35,10 @@ set(INC_SYS
set(SRC
libmv-capi.h
- libmv-capi_intern.h
)
if(WITH_LIBMV)
add_definitions(
- -DWITH_LIBMV
-DWITH_LIBMV_GUARDED_ALLOC
-DGOOGLE_GLOG_DLL_DECL=
-DLIBMV_NO_FAST_DETECTOR=
@@ -66,15 +64,21 @@ if(WITH_LIBMV)
../../intern/guardedalloc
)
- set(INC_SYS
+ list(APPEND INC_SYS
../Eigen3
${PNG_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIRS}
)
list(APPEND SRC
- libmv-capi.cc
- libmv-util.cc
+ intern/camera_intrinsics.cc
+ intern/detector.cc
+ intern/homography.cc
+ intern/image.cc
+ intern/logging.cc
+ intern/reconstruction.cc
+ intern/track_region.cc
+ intern/tracks.cc
libmv/base/aligned_malloc.cc
libmv/image/array_nd.cc
libmv/image/convolve.cc
@@ -109,7 +113,15 @@ if(WITH_LIBMV)
libmv/tracking/track_region.cc
libmv/tracking/trklt_region_tracker.cc
- libmv-util.h
+
+ intern/camera_intrinsics.h
+ intern/detector.h
+ intern/homography.h
+ intern/image.h
+ intern/logging.h
+ intern/reconstruction.h
+ intern/track_region.h
+ intern/tracks.h
libmv/base/aligned_malloc.h
libmv/base/id_generator.h
libmv/base/scoped_ptr.h
@@ -217,7 +229,7 @@ if(WITH_LIBMV)
endif()
else()
list(APPEND SRC
- libmv-capi_stub.cc
+ intern/stub.cc
)
endif()
@@ -228,7 +240,7 @@ if(WITH_LIBMV)
endif()
# make GLog a separate target, so it can be used for gtest as well.
-if(WITH_LIBMV OR WITH_GTESTS)
+if(WITH_LIBMV OR WITH_GTESTS OR WITH_CYCLES_LOGGING)
# We compile GLog together with GFlag so we don't worry about
# adding extra lib to linker.
set(GLOG_SRC
diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript
index 6156dd45146..162fb88df53 100644
--- a/extern/libmv/SConscript
+++ b/extern/libmv/SConscript
@@ -24,11 +24,11 @@ if env['WITH_BF_LIBMV']:
defs.append('CERES_TR1_SHARED_PTR')
defs.append('GOOGLE_GLOG_DLL_DECL=')
- defs.append('WITH_LIBMV')
defs.append('WITH_LIBMV_GUARDED_ALLOC')
defs.append('LIBMV_NO_FAST_DETECTOR')
- src = env.Glob('*.cc')
+ src = env.Glob('intern/*.cc')
+ src.remove('intern' + os.sep + 'stub.cc')
src += env.Glob('libmv/base/*.cc')
src += env.Glob('libmv/image/*.cc')
src += env.Glob('libmv/multiview/*.cc')
@@ -52,7 +52,7 @@ if env['WITH_BF_LIBMV']:
src += env.Glob("third_party/glog/src/*.cc")
incs += ' ./third_party/glog/src'
else:
- src = env.Glob("libmv-capi_stub.cc")
+ src = env.Glob("intern/stub.cc")
src = [src for src in src if src.find('_test.cc') == -1]
diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh
index 0560ab0acd2..f352f77373b 100755
--- a/extern/libmv/bundle.sh
+++ b/extern/libmv/bundle.sh
@@ -7,7 +7,7 @@ else
exit 1
fi
-BRANCH="devel"
+BRANCH="master"
repo="git://git.blender.org/libmv.git"
tmp=`mktemp -d`
@@ -128,12 +128,10 @@ set(INC_SYS
set(SRC
libmv-capi.h
- libmv-capi_intern.h
)
if(WITH_LIBMV)
add_definitions(
- -DWITH_LIBMV
-DWITH_LIBMV_GUARDED_ALLOC
-DGOOGLE_GLOG_DLL_DECL=
-DLIBMV_NO_FAST_DETECTOR=
@@ -159,18 +157,32 @@ if(WITH_LIBMV)
../../intern/guardedalloc
)
- set(INC_SYS
+ list(APPEND INC_SYS
../Eigen3
\${PNG_INCLUDE_DIR}
\${ZLIB_INCLUDE_DIRS}
)
list(APPEND SRC
- libmv-capi.cc
- libmv-util.cc
+ intern/camera_intrinsics.cc
+ intern/detector.cc
+ intern/homography.cc
+ intern/image.cc
+ intern/logging.cc
+ intern/reconstruction.cc
+ intern/track_region.cc
+ intern/tracks.cc
${sources}
${third_sources}
- libmv-util.h
+
+ intern/camera_intrinsics.h
+ intern/detector.h
+ intern/homography.h
+ intern/image.h
+ intern/logging.h
+ intern/reconstruction.h
+ intern/track_region.h
+ intern/tracks.h
${headers}
${third_headers}
@@ -287,11 +299,11 @@ if env['WITH_BF_LIBMV']:
defs.append('CERES_TR1_SHARED_PTR')
defs.append('GOOGLE_GLOG_DLL_DECL=')
- defs.append('WITH_LIBMV')
defs.append('WITH_LIBMV_GUARDED_ALLOC')
defs.append('LIBMV_NO_FAST_DETECTOR')
- src = env.Glob('*.cc')
+ src = env.Glob('intern/*.cc')
+ src.remove('intern' + os.sep + 'stub.cc')
$src
incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
@@ -309,7 +321,7 @@ ${win_src}
src += env.Glob("third_party/glog/src/*.cc")
incs += ' ./third_party/glog/src'
else:
- src = env.Glob("libmv-capi_stub.cc")
+ src = env.Glob("intern/stub.cc")
src = [src for src in src if src.find('_test.cc') == -1]
diff --git a/extern/libmv/intern/camera_intrinsics.cc b/extern/libmv/intern/camera_intrinsics.cc
new file mode 100644
index 00000000000..e8b99970ff7
--- /dev/null
+++ b/extern/libmv/intern/camera_intrinsics.cc
@@ -0,0 +1,354 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/camera_intrinsics.h"
+#include "intern/utildefines.h"
+#include "libmv/simple_pipeline/camera_intrinsics.h"
+
+using libmv::CameraIntrinsics;
+using libmv::DivisionCameraIntrinsics;
+using libmv::PolynomialCameraIntrinsics;
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options) {
+ CameraIntrinsics *camera_intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+ return (libmv_CameraIntrinsics *) camera_intrinsics;
+}
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
+ const libmv_CameraIntrinsics* libmv_intrinsics) {
+ const CameraIntrinsics *orig_intrinsics =
+ (const CameraIntrinsics *) libmv_intrinsics;
+
+ CameraIntrinsics *new_intrinsics = NULL;
+ switch (orig_intrinsics->GetDistortionModelType()) {
+ case libmv::DISTORTION_MODEL_POLYNOMIAL:
+ {
+ const PolynomialCameraIntrinsics *polynomial_intrinsics =
+ static_cast<const PolynomialCameraIntrinsics*>(orig_intrinsics);
+ new_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics,
+ *polynomial_intrinsics);
+ break;
+ }
+ case libmv::DISTORTION_MODEL_DIVISION:
+ {
+ const DivisionCameraIntrinsics *division_intrinsics =
+ static_cast<const DivisionCameraIntrinsics*>(orig_intrinsics);
+ new_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics,
+ *division_intrinsics);
+ break;
+ }
+ default:
+ assert(!"Unknown distortion model");
+ }
+ return (libmv_CameraIntrinsics *) new_intrinsics;
+}
+
+void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics* libmv_intrinsics) {
+ LIBMV_OBJECT_DELETE(libmv_intrinsics, CameraIntrinsics);
+}
+
+void libmv_cameraIntrinsicsUpdate(
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ libmv_CameraIntrinsics* libmv_intrinsics) {
+ CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+
+ double focal_length = libmv_camera_intrinsics_options->focal_length;
+ double principal_x = libmv_camera_intrinsics_options->principal_point_x;
+ double principal_y = libmv_camera_intrinsics_options->principal_point_y;
+ int image_width = libmv_camera_intrinsics_options->image_width;
+ int image_height = libmv_camera_intrinsics_options->image_height;
+
+ /* Try avoid unnecessary updates, so pre-computed distortion grids
+ * are not freed.
+ */
+
+ if (camera_intrinsics->focal_length() != focal_length) {
+ camera_intrinsics->SetFocalLength(focal_length, focal_length);
+ }
+
+ if (camera_intrinsics->principal_point_x() != principal_x ||
+ camera_intrinsics->principal_point_y() != principal_y) {
+ camera_intrinsics->SetPrincipalPoint(principal_x, principal_y);
+ }
+
+ if (camera_intrinsics->image_width() != image_width ||
+ camera_intrinsics->image_height() != image_height) {
+ camera_intrinsics->SetImageSize(image_width, image_height);
+ }
+
+ switch (libmv_camera_intrinsics_options->distortion_model) {
+ case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
+ {
+ assert(camera_intrinsics->GetDistortionModelType() ==
+ libmv::DISTORTION_MODEL_POLYNOMIAL);
+
+ PolynomialCameraIntrinsics *polynomial_intrinsics =
+ (PolynomialCameraIntrinsics *) camera_intrinsics;
+
+ double k1 = libmv_camera_intrinsics_options->polynomial_k1;
+ double k2 = libmv_camera_intrinsics_options->polynomial_k2;
+ double k3 = libmv_camera_intrinsics_options->polynomial_k3;
+
+ if (polynomial_intrinsics->k1() != k1 ||
+ polynomial_intrinsics->k2() != k2 ||
+ polynomial_intrinsics->k3() != k3) {
+ polynomial_intrinsics->SetRadialDistortion(k1, k2, k3);
+ }
+ break;
+ }
+
+ case LIBMV_DISTORTION_MODEL_DIVISION:
+ {
+ assert(camera_intrinsics->GetDistortionModelType() ==
+ libmv::DISTORTION_MODEL_DIVISION);
+
+ DivisionCameraIntrinsics *division_intrinsics =
+ (DivisionCameraIntrinsics *) camera_intrinsics;
+
+ double k1 = libmv_camera_intrinsics_options->division_k1;
+ double k2 = libmv_camera_intrinsics_options->division_k2;
+
+ if (division_intrinsics->k1() != k1 ||
+ division_intrinsics->k2() != k2) {
+ division_intrinsics->SetDistortion(k1, k2);
+ }
+
+ break;
+ }
+
+ default:
+ assert(!"Unknown distortion model");
+ }
+}
+
+void libmv_cameraIntrinsicsSetThreads(libmv_CameraIntrinsics* libmv_intrinsics,
+ int threads) {
+ CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+ camera_intrinsics->SetThreads(threads);
+}
+
+void libmv_cameraIntrinsicsExtractOptions(
+ const libmv_CameraIntrinsics* libmv_intrinsics,
+ libmv_CameraIntrinsicsOptions* camera_intrinsics_options) {
+ const CameraIntrinsics *camera_intrinsics =
+ (const CameraIntrinsics *) libmv_intrinsics;
+
+ // Fill in options which are common for all distortion models.
+ camera_intrinsics_options->focal_length = camera_intrinsics->focal_length();
+ camera_intrinsics_options->principal_point_x =
+ camera_intrinsics->principal_point_x();
+ camera_intrinsics_options->principal_point_y =
+ camera_intrinsics->principal_point_y();
+
+ camera_intrinsics_options->image_width = camera_intrinsics->image_width();
+ camera_intrinsics_options->image_height = camera_intrinsics->image_height();
+
+ switch (camera_intrinsics->GetDistortionModelType()) {
+ case libmv::DISTORTION_MODEL_POLYNOMIAL:
+ {
+ const PolynomialCameraIntrinsics *polynomial_intrinsics =
+ static_cast<const PolynomialCameraIntrinsics *>(camera_intrinsics);
+ camera_intrinsics_options->distortion_model =
+ LIBMV_DISTORTION_MODEL_POLYNOMIAL;
+ camera_intrinsics_options->polynomial_k1 = polynomial_intrinsics->k1();
+ camera_intrinsics_options->polynomial_k2 = polynomial_intrinsics->k2();
+ camera_intrinsics_options->polynomial_k3 = polynomial_intrinsics->k3();
+ camera_intrinsics_options->polynomial_p1 = polynomial_intrinsics->p1();
+ camera_intrinsics_options->polynomial_p1 = polynomial_intrinsics->p2();
+ break;
+ }
+
+ case libmv::DISTORTION_MODEL_DIVISION:
+ {
+ const DivisionCameraIntrinsics *division_intrinsics =
+ static_cast<const DivisionCameraIntrinsics *>(camera_intrinsics);
+ camera_intrinsics_options->distortion_model =
+ LIBMV_DISTORTION_MODEL_DIVISION;
+ camera_intrinsics_options->division_k1 = division_intrinsics->k1();
+ camera_intrinsics_options->division_k2 = division_intrinsics->k2();
+ break;
+ }
+
+ default:
+ assert(!"Uknown distortion model");
+ }
+}
+
+void libmv_cameraIntrinsicsUndistortByte(
+ const libmv_CameraIntrinsics* libmv_intrinsics,
+ const unsigned char *source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ unsigned char* destination_image) {
+ CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+ camera_intrinsics->UndistortBuffer(source_image,
+ width, height,
+ overscan,
+ channels,
+ destination_image);
+}
+
+void libmv_cameraIntrinsicsUndistortFloat(
+ const libmv_CameraIntrinsics* libmv_intrinsics,
+ const float* source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ float* destination_image) {
+ CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+ intrinsics->UndistortBuffer(source_image,
+ width, height,
+ overscan,
+ channels,
+ destination_image);
+}
+
+void libmv_cameraIntrinsicsDistortByte(
+ const struct libmv_CameraIntrinsics* libmv_intrinsics,
+ const unsigned char *source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ unsigned char *destination_image) {
+ CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+ intrinsics->DistortBuffer(source_image,
+ width, height,
+ overscan,
+ channels,
+ destination_image);
+}
+
+void libmv_cameraIntrinsicsDistortFloat(
+ const libmv_CameraIntrinsics* libmv_intrinsics,
+ float* source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ float* destination_image) {
+ CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmv_intrinsics;
+ intrinsics->DistortBuffer(source_image,
+ width, height,
+ overscan,
+ channels,
+ destination_image);
+}
+
+void libmv_cameraIntrinsicsApply(
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ double x,
+ double y,
+ double* x1,
+ double* y1) {
+ /* Do a lens distortion if focal length is non-zero only. */
+ if (libmv_camera_intrinsics_options->focal_length) {
+ CameraIntrinsics* camera_intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+ camera_intrinsics->ApplyIntrinsics(x, y, x1, y1);
+ LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
+ }
+}
+
+void libmv_cameraIntrinsicsInvert(
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ double x,
+ double y,
+ double* x1,
+ double* y1) {
+ /* Do a lens un-distortion if focal length is non-zero only/ */
+ if (libmv_camera_intrinsics_options->focal_length) {
+ CameraIntrinsics *camera_intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+ camera_intrinsics->InvertIntrinsics(x, y, x1, y1);
+ LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
+ }
+}
+
+static void libmv_cameraIntrinsicsFillFromOptions(
+ const libmv_CameraIntrinsicsOptions* camera_intrinsics_options,
+ CameraIntrinsics* camera_intrinsics) {
+ camera_intrinsics->SetFocalLength(camera_intrinsics_options->focal_length,
+ camera_intrinsics_options->focal_length);
+
+ camera_intrinsics->SetPrincipalPoint(
+ camera_intrinsics_options->principal_point_x,
+ camera_intrinsics_options->principal_point_y);
+
+ camera_intrinsics->SetImageSize(camera_intrinsics_options->image_width,
+ camera_intrinsics_options->image_height);
+
+ switch (camera_intrinsics_options->distortion_model) {
+ case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
+ {
+ PolynomialCameraIntrinsics *polynomial_intrinsics =
+ static_cast<PolynomialCameraIntrinsics*>(camera_intrinsics);
+
+ polynomial_intrinsics->SetRadialDistortion(
+ camera_intrinsics_options->polynomial_k1,
+ camera_intrinsics_options->polynomial_k2,
+ camera_intrinsics_options->polynomial_k3);
+
+ break;
+ }
+
+ case LIBMV_DISTORTION_MODEL_DIVISION:
+ {
+ DivisionCameraIntrinsics *division_intrinsics =
+ static_cast<DivisionCameraIntrinsics*>(camera_intrinsics);
+
+ division_intrinsics->SetDistortion(
+ camera_intrinsics_options->division_k1,
+ camera_intrinsics_options->division_k2);
+ break;
+ }
+
+ default:
+ assert(!"Unknown distortion model");
+ }
+}
+
+CameraIntrinsics* libmv_cameraIntrinsicsCreateFromOptions(
+ const libmv_CameraIntrinsicsOptions* camera_intrinsics_options) {
+ CameraIntrinsics *camera_intrinsics = NULL;
+ switch (camera_intrinsics_options->distortion_model) {
+ case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
+ camera_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics);
+ break;
+ case LIBMV_DISTORTION_MODEL_DIVISION:
+ camera_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics);
+ break;
+ default:
+ assert(!"Unknown distortion model");
+ }
+ libmv_cameraIntrinsicsFillFromOptions(camera_intrinsics_options, camera_intrinsics);
+ return camera_intrinsics;
+}
diff --git a/extern/libmv/intern/camera_intrinsics.h b/extern/libmv/intern/camera_intrinsics.h
new file mode 100644
index 00000000000..9910d16a108
--- /dev/null
+++ b/extern/libmv/intern/camera_intrinsics.h
@@ -0,0 +1,138 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_CAMERA_INTRINSICS_H_
+#define LIBMV_C_API_CAMERA_INTRINSICS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_CameraIntrinsics libmv_CameraIntrinsics;
+
+enum {
+ LIBMV_DISTORTION_MODEL_POLYNOMIAL = 0,
+ LIBMV_DISTORTION_MODEL_DIVISION = 1,
+};
+
+typedef struct libmv_CameraIntrinsicsOptions {
+ // Common settings of all distortion models.
+ int distortion_model;
+ int image_width, image_height;
+ double focal_length;
+ double principal_point_x, principal_point_y;
+
+ // Radial distortion model.
+ double polynomial_k1, polynomial_k2, polynomial_k3;
+ double polynomial_p1, polynomial_p2;
+
+ // Division distortion model.
+ double division_k1, division_k2;
+} libmv_CameraIntrinsicsOptions;
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options);
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
+ const libmv_CameraIntrinsics* libmv_intrinsics);
+
+void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics* libmv_intrinsics);
+void libmv_cameraIntrinsicsUpdate(
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ libmv_CameraIntrinsics* libmv_intrinsics);
+
+void libmv_cameraIntrinsicsSetThreads(libmv_CameraIntrinsics* libmv_intrinsics,
+ int threads);
+
+void libmv_cameraIntrinsicsExtractOptions(
+ const libmv_CameraIntrinsics* libmv_intrinsics,
+ libmv_CameraIntrinsicsOptions* camera_intrinsics_options);
+
+void libmv_cameraIntrinsicsUndistortByte(
+ const libmv_CameraIntrinsics* libmv_intrinsics,
+ const unsigned char *source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ unsigned char* destination_image);
+
+void libmv_cameraIntrinsicsUndistortFloat(
+ const libmv_CameraIntrinsics* libmv_intrinsics,
+ const float* source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ float* destination_image);
+
+void libmv_cameraIntrinsicsDistortByte(
+ const struct libmv_CameraIntrinsics* libmv_intrinsics,
+ const unsigned char *source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ unsigned char *destination_image);
+
+void libmv_cameraIntrinsicsDistortFloat(
+ const libmv_CameraIntrinsics* libmv_intrinsics,
+ float* source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ float* destination_image);
+
+void libmv_cameraIntrinsicsApply(
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ double x,
+ double y,
+ double* x1,
+ double* y1);
+
+void libmv_cameraIntrinsicsInvert(
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ double x,
+ double y,
+ double* x1,
+ double* y1);
+
+#ifdef __cplusplus
+}
+#endif
+
+#ifdef __cplusplus
+
+namespace libmv {
+ class CameraIntrinsics;
+}
+
+libmv::CameraIntrinsics* libmv_cameraIntrinsicsCreateFromOptions(
+ const libmv_CameraIntrinsicsOptions* camera_intrinsics_options);
+#endif
+
+#endif // LIBMV_C_API_CAMERA_INTRINSICS_H_
diff --git a/extern/libmv/intern/detector.cc b/extern/libmv/intern/detector.cc
new file mode 100644
index 00000000000..8abc9014115
--- /dev/null
+++ b/extern/libmv/intern/detector.cc
@@ -0,0 +1,148 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/detector.h"
+#include "intern/image.h"
+#include "intern/utildefines.h"
+#include "libmv/simple_pipeline/detect.h"
+
+using libmv::Detect;
+using libmv::DetectOptions;
+using libmv::Feature;
+using libmv::FloatImage;
+
+struct libmv_Features {
+ int count;
+ Feature* features;
+};
+
+namespace {
+
+libmv_Features *libmv_featuresFromVector(
+ const libmv::vector<Feature>& features) {
+ libmv_Features* libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
+ int count = features.size();
+ if (count) {
+ libmv_features->features = LIBMV_STRUCT_NEW(Feature, count);
+ for (int i = 0; i < count; i++) {
+ libmv_features->features[i] = features.at(i);
+ }
+ } else {
+ libmv_features->features = NULL;
+ }
+ libmv_features->count = count;
+ return libmv_features;
+}
+
+void libmv_convertDetectorOptions(libmv_DetectOptions *options,
+ DetectOptions *detector_options) {
+ switch (options->detector) {
+#define LIBMV_CONVERT(the_detector) \
+ case LIBMV_DETECTOR_ ## the_detector: \
+ detector_options->type = DetectOptions::the_detector; \
+ break;
+ LIBMV_CONVERT(FAST)
+ LIBMV_CONVERT(MORAVEC)
+ LIBMV_CONVERT(HARRIS)
+#undef LIBMV_CONVERT
+ }
+ detector_options->margin = options->margin;
+ detector_options->min_distance = options->min_distance;
+ detector_options->fast_min_trackness = options->fast_min_trackness;
+ detector_options->moravec_max_count = options->moravec_max_count;
+ detector_options->moravec_pattern = options->moravec_pattern;
+ detector_options->harris_threshold = options->harris_threshold;
+}
+
+} // namespace
+
+libmv_Features *libmv_detectFeaturesByte(const unsigned char* image_buffer,
+ int width,
+ int height,
+ int channels,
+ libmv_DetectOptions* options) {
+ // Prepare the image.
+ FloatImage image;
+ libmv_byteBufferToFloatImage(image_buffer, width, height, channels, &image);
+
+ // Configure detector.
+ DetectOptions detector_options;
+ libmv_convertDetectorOptions(options, &detector_options);
+
+ // Run the detector.
+ libmv::vector<Feature> detected_features;
+ Detect(image, detector_options, &detected_features);
+
+ // Convert result to C-API.
+ libmv_Features* result = libmv_featuresFromVector(detected_features);
+ return result;
+}
+
+libmv_Features* libmv_detectFeaturesFloat(const float* image_buffer,
+ int width,
+ int height,
+ int channels,
+ libmv_DetectOptions* options) {
+ // Prepare the image.
+ FloatImage image;
+ libmv_floatBufferToFloatImage(image_buffer, width, height, channels, &image);
+
+ // Configure detector.
+ DetectOptions detector_options;
+ libmv_convertDetectorOptions(options, &detector_options);
+
+ // Run the detector.
+ libmv::vector<Feature> detected_features;
+ Detect(image, detector_options, &detected_features);
+
+ // Convert result to C-API.
+ libmv_Features* result = libmv_featuresFromVector(detected_features);
+ return result;
+}
+
+void libmv_featuresDestroy(libmv_Features* libmv_features) {
+ if (libmv_features->features) {
+ LIBMV_STRUCT_DELETE(libmv_features->features);
+ }
+ LIBMV_STRUCT_DELETE(libmv_features);
+}
+
+int libmv_countFeatures(const libmv_Features* libmv_features) {
+ return libmv_features->count;
+}
+
+void libmv_getFeature(const libmv_Features* libmv_features,
+ int number,
+ double* x,
+ double* y,
+ double* score,
+ double* size) {
+ Feature &feature = libmv_features->features[number];
+ *x = feature.x;
+ *y = feature.y;
+ *score = feature.score;
+ *size = feature.size;
+}
diff --git a/extern/libmv/intern/detector.h b/extern/libmv/intern/detector.h
new file mode 100644
index 00000000000..f72b0dd8d6e
--- /dev/null
+++ b/extern/libmv/intern/detector.h
@@ -0,0 +1,77 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_DETECTOR_H_
+#define LIBMV_C_API_DETECTOR_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_Features libmv_Features;
+
+enum {
+ LIBMV_DETECTOR_FAST,
+ LIBMV_DETECTOR_MORAVEC,
+ LIBMV_DETECTOR_HARRIS,
+};
+
+typedef struct libmv_DetectOptions {
+ int detector;
+ int margin;
+ int min_distance;
+ int fast_min_trackness;
+ int moravec_max_count;
+ unsigned char *moravec_pattern;
+ double harris_threshold;
+} libmv_DetectOptions;
+
+libmv_Features* libmv_detectFeaturesByte(const unsigned char* image_buffer,
+ int width,
+ int height,
+ int channels,
+ libmv_DetectOptions* options);
+
+libmv_Features* libmv_detectFeaturesFloat(const float* image_buffer,
+ int width,
+ int height,
+ int channels,
+ libmv_DetectOptions* options);
+
+void libmv_featuresDestroy(libmv_Features* libmv_features);
+int libmv_countFeatures(const libmv_Features* libmv_features);
+void libmv_getFeature(const libmv_Features* libmv_features,
+ int number,
+ double* x,
+ double* y,
+ double* score,
+ double* size);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_DETECTOR_H_
diff --git a/extern/libmv/intern/homography.cc b/extern/libmv/intern/homography.cc
new file mode 100644
index 00000000000..6b61bd9ab42
--- /dev/null
+++ b/extern/libmv/intern/homography.cc
@@ -0,0 +1,59 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/homography.h"
+#include "intern/utildefines.h"
+#include "libmv/logging/logging.h"
+#include "libmv/multiview/homography.h"
+
+void libmv_homography2DFromCorrespondencesEuc(/* const */ double (*x1)[2],
+ /* const */ double (*x2)[2],
+ int num_points,
+ double H[3][3]) {
+ libmv::Mat x1_mat, x2_mat;
+ libmv::Mat3 H_mat;
+
+ x1_mat.resize(2, num_points);
+ x2_mat.resize(2, num_points);
+
+ for (int i = 0; i < num_points; i++) {
+ x1_mat.col(i) = libmv::Vec2(x1[i][0], x1[i][1]);
+ x2_mat.col(i) = libmv::Vec2(x2[i][0], x2[i][1]);
+ }
+
+ LG << "x1: " << x1_mat;
+ LG << "x2: " << x2_mat;
+
+ libmv::EstimateHomographyOptions options;
+ libmv::EstimateHomography2DFromCorrespondences(x1_mat,
+ x2_mat,
+ options,
+ &H_mat);
+
+ LG << "H: " << H_mat;
+
+ memcpy(H, H_mat.data(), 9 * sizeof(double));
+}
diff --git a/extern/libmv/intern/homography.h b/extern/libmv/intern/homography.h
new file mode 100644
index 00000000000..175108e8171
--- /dev/null
+++ b/extern/libmv/intern/homography.h
@@ -0,0 +1,43 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_HOMOGRAPHY_H_
+#define LIBMV_C_API_HOMOGRAPHY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void libmv_homography2DFromCorrespondencesEuc(/* const */ double (*x1)[2],
+ /* const */ double (*x2)[2],
+ int num_points,
+ double H[3][3]);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_HOMOGRAPHY_H_
diff --git a/extern/libmv/intern/image.cc b/extern/libmv/intern/image.cc
new file mode 100644
index 00000000000..7e623bdbec7
--- /dev/null
+++ b/extern/libmv/intern/image.cc
@@ -0,0 +1,272 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/image.h"
+#include "intern/utildefines.h"
+#include "libmv/tracking/track_region.h"
+
+#include <cassert>
+#include <png.h>
+
+using libmv::FloatImage;
+using libmv::SamplePlanarPatch;
+
+void libmv_floatImaheDestroy(libmv_FloatImage *image) {
+ delete [] image->buffer;
+}
+
+/* Image <-> buffers conversion */
+
+void libmv_byteBufferToFloatImage(const unsigned char* buffer,
+ int width,
+ int height,
+ int channels,
+ FloatImage* image) {
+ image->Resize(height, width, channels);
+ for (int y = 0, a = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ for (int k = 0; k < channels; k++) {
+ (*image)(y, x, k) = (float)buffer[a++] / 255.0f;
+ }
+ }
+ }
+}
+
+void libmv_floatBufferToFloatImage(const float* buffer,
+ int width,
+ int height,
+ int channels,
+ FloatImage* image) {
+ image->Resize(height, width, channels);
+ for (int y = 0, a = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ for (int k = 0; k < channels; k++) {
+ (*image)(y, x, k) = buffer[a++];
+ }
+ }
+ }
+}
+
+void libmv_floatImageToFloatBuffer(const FloatImage &image,
+ float* buffer) {
+ for (int y = 0, a = 0; y < image.Height(); y++) {
+ for (int x = 0; x < image.Width(); x++) {
+ for (int k = 0; k < image.Depth(); k++) {
+ buffer[a++] = image(y, x, k);
+ }
+ }
+ }
+}
+
+void libmv_floatImageToByteBuffer(const libmv::FloatImage &image,
+ unsigned char* buffer) {
+ for (int y = 0, a= 0; y < image.Height(); y++) {
+ for (int x = 0; x < image.Width(); x++) {
+ for (int k = 0; k < image.Depth(); k++) {
+ buffer[a++] = image(y, x, k) * 255.0f;
+ }
+ }
+ }
+}
+
+static bool savePNGImage(png_bytep* row_pointers,
+ int width,
+ int height,
+ int depth,
+ int color_type,
+ const char* file_name) {
+ png_infop info_ptr;
+ png_structp png_ptr;
+ FILE *fp = fopen(file_name, "wb");
+
+ if (fp == NULL) {
+ return false;
+ }
+
+ /* Initialize stuff */
+ png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ info_ptr = png_create_info_struct(png_ptr);
+
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ fclose(fp);
+ return false;
+ }
+
+ png_init_io(png_ptr, fp);
+
+ /* Write PNG header. */
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ fclose(fp);
+ return false;
+ }
+
+ png_set_IHDR(png_ptr,
+ info_ptr,
+ width,
+ height,
+ depth,
+ color_type,
+ PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE,
+ PNG_FILTER_TYPE_BASE);
+
+ png_write_info(png_ptr, info_ptr);
+
+ /* Write bytes/ */
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ fclose(fp);
+ return false;
+ }
+
+ png_write_image(png_ptr, row_pointers);
+
+ /* End write/ */
+ if (setjmp(png_jmpbuf(png_ptr))) {
+ fclose(fp);
+ return false;
+ }
+
+ png_write_end(png_ptr, NULL);
+ fclose(fp);
+
+ return true;
+}
+
+bool libmv_saveImage(const FloatImage& image,
+ const char* prefix,
+ int x0,
+ int y0) {
+ int x, y;
+ png_bytep *row_pointers;
+
+ assert(image.Depth() == 1);
+
+ row_pointers = new png_bytep[image.Height()];
+
+ for (y = 0; y < image.Height(); y++) {
+ row_pointers[y] = new png_byte[4 * image.Width()];
+
+ for (x = 0; x < image.Width(); x++) {
+ if (x0 == x && image.Height() - y0 - 1 == y) {
+ row_pointers[y][x * 4 + 0] = 255;
+ row_pointers[y][x * 4 + 1] = 0;
+ row_pointers[y][x * 4 + 2] = 0;
+ row_pointers[y][x * 4 + 3] = 255;
+ } else {
+ float pixel = image(image.Height() - y - 1, x, 0);
+ row_pointers[y][x * 4 + 0] = pixel * 255;
+ row_pointers[y][x * 4 + 1] = pixel * 255;
+ row_pointers[y][x * 4 + 2] = pixel * 255;
+ row_pointers[y][x * 4 + 3] = 255;
+ }
+ }
+ }
+
+ static int image_counter = 0;
+ char file_name[128];
+ snprintf(file_name, sizeof(file_name),
+ "%s_%02d.png",
+ prefix, ++image_counter);
+ bool result = savePNGImage(row_pointers,
+ image.Width(),
+ image.Height(),
+ 8,
+ PNG_COLOR_TYPE_RGBA,
+ file_name);
+
+ for (y = 0; y < image.Height(); y++) {
+ delete [] row_pointers[y];
+ }
+ delete [] row_pointers;
+
+ return result;
+}
+
+void libmv_samplePlanarPatchFloat(const float* image,
+ int width,
+ int height,
+ int channels,
+ const double* xs,
+ const double* ys,
+ int num_samples_x,
+ int num_samples_y,
+ const float* mask,
+ float* patch,
+ double* warped_position_x,
+ double* warped_position_y) {
+ FloatImage libmv_image, libmv_patch, libmv_mask;
+ FloatImage *libmv_mask_for_sample = NULL;
+
+ libmv_floatBufferToFloatImage(image, width, height, channels, &libmv_image);
+
+ if (mask) {
+ libmv_floatBufferToFloatImage(mask, width, height, 1, &libmv_mask);
+ libmv_mask_for_sample = &libmv_mask;
+ }
+
+ SamplePlanarPatch(libmv_image,
+ xs, ys,
+ num_samples_x, num_samples_y,
+ libmv_mask_for_sample,
+ &libmv_patch,
+ warped_position_x,
+ warped_position_y);
+
+ libmv_floatImageToFloatBuffer(libmv_patch, patch);
+}
+
+ void libmv_samplePlanarPatchByte(const unsigned char* image,
+ int width,
+ int height,
+ int channels,
+ const double* xs,
+ const double* ys,
+ int num_samples_x,
+ int num_samples_y,
+ const float* mask,
+ unsigned char* patch,
+ double* warped_position_x,
+ double* warped_position_y) {
+ libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
+ libmv::FloatImage *libmv_mask_for_sample = NULL;
+
+ libmv_byteBufferToFloatImage(image, width, height, channels, &libmv_image);
+
+ if (mask) {
+ libmv_floatBufferToFloatImage(mask, width, height, 1, &libmv_mask);
+ libmv_mask_for_sample = &libmv_mask;
+ }
+
+ libmv::SamplePlanarPatch(libmv_image,
+ xs, ys,
+ num_samples_x, num_samples_y,
+ libmv_mask_for_sample,
+ &libmv_patch,
+ warped_position_x,
+ warped_position_y);
+
+ libmv_floatImageToByteBuffer(libmv_patch, patch);
+}
diff --git a/extern/libmv/intern/image.h b/extern/libmv/intern/image.h
new file mode 100644
index 00000000000..9936e748b9d
--- /dev/null
+++ b/extern/libmv/intern/image.h
@@ -0,0 +1,99 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_IMAGE_H_
+#define LIBMV_IMAGE_H_
+
+#ifdef __cplusplus
+# include "libmv/image/image.h"
+void libmv_byteBufferToFloatImage(const unsigned char* buffer,
+ int width,
+ int height,
+ int channels,
+ libmv::FloatImage* image);
+
+void libmv_floatBufferToFloatImage(const float* buffer,
+ int width,
+ int height,
+ int channels,
+ libmv::FloatImage* image);
+
+void libmv_floatImageToFloatBuffer(const libmv::FloatImage& image,
+ float *buffer);
+
+void libmv_floatImageToByteBuffer(const libmv::FloatImage& image,
+ unsigned char* buffer);
+
+bool libmv_saveImage(const libmv::FloatImage& image,
+ const char* prefix,
+ int x0,
+ int y0);
+#endif // __cplusplus
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_FloatImage {
+ float *buffer;
+ int width;
+ int height;
+ int channels;
+} libmv_FloatImage;
+
+void libmv_floatImaheDestroy(libmv_FloatImage *image);
+
+void libmv_samplePlanarPatchFloat(const float* image,
+ int width,
+ int height,
+ int channels,
+ const double* xs,
+ const double* ys,
+ int num_samples_x,
+ int num_samples_y,
+ const float* mask,
+ float* patch,
+ double* warped_position_x,
+ double* warped_position_y);
+
+ void libmv_samplePlanarPatchByte(const unsigned char* image,
+ int width,
+ int height,
+ int channels,
+ const double* xs,
+ const double* ys,
+ int num_samples_x,
+ int num_samples_y,
+ const float* mask,
+ unsigned char* patch,
+ double* warped_position_x,
+ double* warped_position_y);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_IMAGE_H_
diff --git a/extern/libmv/intern/logging.cc b/extern/libmv/intern/logging.cc
new file mode 100644
index 00000000000..4ab2d91c8b4
--- /dev/null
+++ b/extern/libmv/intern/logging.cc
@@ -0,0 +1,55 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/logging.h"
+#include "intern/utildefines.h"
+#include "libmv/logging/logging.h"
+
+void libmv_initLogging(const char* argv0) {
+ // Make it so FATAL messages are always print into console.
+ char severity_fatal[32];
+ snprintf(severity_fatal, sizeof(severity_fatal), "%d",
+ google::GLOG_FATAL);
+
+ google::InitGoogleLogging(argv0);
+ google::SetCommandLineOption("logtostderr", "1");
+ google::SetCommandLineOption("v", "0");
+ google::SetCommandLineOption("stderrthreshold", severity_fatal);
+ google::SetCommandLineOption("minloglevel", severity_fatal);
+}
+
+void libmv_startDebugLogging(void) {
+ google::SetCommandLineOption("logtostderr", "1");
+ google::SetCommandLineOption("v", "2");
+ google::SetCommandLineOption("stderrthreshold", "1");
+ google::SetCommandLineOption("minloglevel", "0");
+}
+
+void libmv_setLoggingVerbosity(int verbosity) {
+ char val[10];
+ snprintf(val, sizeof(val), "%d", verbosity);
+ google::SetCommandLineOption("v", val);
+}
diff --git a/extern/libmv/intern/logging.h b/extern/libmv/intern/logging.h
new file mode 100644
index 00000000000..479ed3d6288
--- /dev/null
+++ b/extern/libmv/intern/logging.h
@@ -0,0 +1,47 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_LOGGING_H_
+#define LIBMV_C_API_LOGGING_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Initialize GLog logging.
+void libmv_initLogging(const char* argv0);
+
+// Switch Glog to debug logging level.
+void libmv_startDebugLogging(void);
+
+// Set GLog logging verbosity level.
+void libmv_setLoggingVerbosity(int verbosity);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_LOGGING_H_
diff --git a/extern/libmv/intern/reconstruction.cc b/extern/libmv/intern/reconstruction.cc
new file mode 100644
index 00000000000..eb3677fd206
--- /dev/null
+++ b/extern/libmv/intern/reconstruction.cc
@@ -0,0 +1,530 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/reconstruction.h"
+#include "intern/camera_intrinsics.h"
+#include "intern/tracks.h"
+#include "intern/utildefines.h"
+
+#include "libmv/logging/logging.h"
+#include "libmv/simple_pipeline/bundle.h"
+#include "libmv/simple_pipeline/keyframe_selection.h"
+#include "libmv/simple_pipeline/initialize_reconstruction.h"
+#include "libmv/simple_pipeline/modal_solver.h"
+#include "libmv/simple_pipeline/pipeline.h"
+#include "libmv/simple_pipeline/reconstruction_scale.h"
+#include "libmv/simple_pipeline/tracks.h"
+
+using libmv::CameraIntrinsics;
+using libmv::EuclideanCamera;
+using libmv::EuclideanPoint;
+using libmv::EuclideanReconstruction;
+using libmv::EuclideanScaleToUnity;
+using libmv::Marker;
+using libmv::ProgressUpdateCallback;
+
+using libmv::PolynomialCameraIntrinsics;
+using libmv::Tracks;
+using libmv::EuclideanBundle;
+using libmv::EuclideanCompleteReconstruction;
+using libmv::EuclideanReconstructTwoFrames;
+using libmv::EuclideanReprojectionError;
+
+struct libmv_Reconstruction {
+ EuclideanReconstruction reconstruction;
+
+ /* Used for per-track average error calculation after reconstruction */
+ Tracks tracks;
+ CameraIntrinsics *intrinsics;
+
+ double error;
+};
+
+namespace {
+
+class ReconstructUpdateCallback : public ProgressUpdateCallback {
+ public:
+ ReconstructUpdateCallback(
+ reconstruct_progress_update_cb progress_update_callback,
+ void *callback_customdata) {
+ progress_update_callback_ = progress_update_callback;
+ callback_customdata_ = callback_customdata;
+ }
+
+ void invoke(double progress, const char* message) {
+ if (progress_update_callback_) {
+ progress_update_callback_(callback_customdata_, progress, message);
+ }
+ }
+ protected:
+ reconstruct_progress_update_cb progress_update_callback_;
+ void* callback_customdata_;
+};
+
+void libmv_solveRefineIntrinsics(
+ const Tracks &tracks,
+ const int refine_intrinsics,
+ const int bundle_constraints,
+ reconstruct_progress_update_cb progress_update_callback,
+ void* callback_customdata,
+ EuclideanReconstruction* reconstruction,
+ CameraIntrinsics* intrinsics) {
+ /* only a few combinations are supported but trust the caller/ */
+ int bundle_intrinsics = 0;
+
+ if (refine_intrinsics & LIBMV_REFINE_FOCAL_LENGTH) {
+ bundle_intrinsics |= libmv::BUNDLE_FOCAL_LENGTH;
+ }
+ if (refine_intrinsics & LIBMV_REFINE_PRINCIPAL_POINT) {
+ bundle_intrinsics |= libmv::BUNDLE_PRINCIPAL_POINT;
+ }
+ if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K1) {
+ bundle_intrinsics |= libmv::BUNDLE_RADIAL_K1;
+ }
+ if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K2) {
+ bundle_intrinsics |= libmv::BUNDLE_RADIAL_K2;
+ }
+
+ progress_update_callback(callback_customdata, 1.0, "Refining solution");
+
+ EuclideanBundleCommonIntrinsics(tracks,
+ bundle_intrinsics,
+ bundle_constraints,
+ reconstruction,
+ intrinsics);
+}
+
+void finishReconstruction(
+ const Tracks &tracks,
+ const CameraIntrinsics &camera_intrinsics,
+ libmv_Reconstruction *libmv_reconstruction,
+ reconstruct_progress_update_cb progress_update_callback,
+ void *callback_customdata) {
+ EuclideanReconstruction &reconstruction =
+ libmv_reconstruction->reconstruction;
+
+ /* Reprojection error calculation. */
+ progress_update_callback(callback_customdata, 1.0, "Finishing solution");
+ libmv_reconstruction->tracks = tracks;
+ libmv_reconstruction->error = EuclideanReprojectionError(tracks,
+ reconstruction,
+ camera_intrinsics);
+}
+
+bool selectTwoKeyframesBasedOnGRICAndVariance(
+ Tracks& tracks,
+ Tracks& normalized_tracks,
+ CameraIntrinsics& camera_intrinsics,
+ int& keyframe1,
+ int& keyframe2) {
+ libmv::vector<int> keyframes;
+
+ /* Get list of all keyframe candidates first. */
+ SelectKeyframesBasedOnGRICAndVariance(normalized_tracks,
+ camera_intrinsics,
+ keyframes);
+
+ if (keyframes.size() < 2) {
+ LG << "Not enough keyframes detected by GRIC";
+ return false;
+ } else if (keyframes.size() == 2) {
+ keyframe1 = keyframes[0];
+ keyframe2 = keyframes[1];
+ return true;
+ }
+
+ /* Now choose two keyframes with minimal reprojection error after initial
+ * reconstruction choose keyframes with the least reprojection error after
+ * solving from two candidate keyframes.
+ *
+ * In fact, currently libmv returns single pair only, so this code will
+ * not actually run. But in the future this could change, so let's stay
+ * prepared.
+ */
+ int previous_keyframe = keyframes[0];
+ double best_error = std::numeric_limits<double>::max();
+ for (int i = 1; i < keyframes.size(); i++) {
+ EuclideanReconstruction reconstruction;
+ int current_keyframe = keyframes[i];
+ libmv::vector<Marker> keyframe_markers =
+ normalized_tracks.MarkersForTracksInBothImages(previous_keyframe,
+ current_keyframe);
+
+ Tracks keyframe_tracks(keyframe_markers);
+
+ /* get a solution from two keyframes only */
+ EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
+ EuclideanBundle(keyframe_tracks, &reconstruction);
+ EuclideanCompleteReconstruction(keyframe_tracks,
+ &reconstruction,
+ NULL);
+
+ double current_error = EuclideanReprojectionError(tracks,
+ reconstruction,
+ camera_intrinsics);
+
+ LG << "Error between " << previous_keyframe
+ << " and " << current_keyframe
+ << ": " << current_error;
+
+ if (current_error < best_error) {
+ best_error = current_error;
+ keyframe1 = previous_keyframe;
+ keyframe2 = current_keyframe;
+ }
+
+ previous_keyframe = current_keyframe;
+ }
+
+ return true;
+}
+
+Marker libmv_projectMarker(const EuclideanPoint& point,
+ const EuclideanCamera& camera,
+ const CameraIntrinsics& intrinsics) {
+ libmv::Vec3 projected = camera.R * point.X + camera.t;
+ projected /= projected(2);
+
+ libmv::Marker reprojected_marker;
+ intrinsics.ApplyIntrinsics(projected(0), projected(1),
+ &reprojected_marker.x,
+ &reprojected_marker.y);
+
+ reprojected_marker.image = camera.image;
+ reprojected_marker.track = point.track;
+ return reprojected_marker;
+}
+
+void libmv_getNormalizedTracks(const Tracks &tracks,
+ const CameraIntrinsics &camera_intrinsics,
+ Tracks *normalized_tracks)
+{
+ libmv::vector<Marker> markers = tracks.AllMarkers();
+ for (int i = 0; i < markers.size(); ++i) {
+ Marker &marker = markers[i];
+ camera_intrinsics.InvertIntrinsics(marker.x, marker.y,
+ &marker.x, &marker.y);
+ normalized_tracks->Insert(marker.image,
+ marker.track,
+ marker.x, marker.y,
+ marker.weight);
+ }
+}
+
+} // namespace
+
+libmv_Reconstruction *libmv_solveReconstruction(
+ const libmv_Tracks* libmv_tracks,
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ libmv_ReconstructionOptions* libmv_reconstruction_options,
+ reconstruct_progress_update_cb progress_update_callback,
+ void* callback_customdata) {
+ libmv_Reconstruction *libmv_reconstruction =
+ LIBMV_OBJECT_NEW(libmv_Reconstruction);
+
+ Tracks &tracks = *((Tracks *) libmv_tracks);
+ EuclideanReconstruction &reconstruction =
+ libmv_reconstruction->reconstruction;
+
+ ReconstructUpdateCallback update_callback =
+ ReconstructUpdateCallback(progress_update_callback,
+ callback_customdata);
+
+ /* Retrieve reconstruction options from C-API to libmv API. */
+ CameraIntrinsics *camera_intrinsics;
+ camera_intrinsics = libmv_reconstruction->intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
+
+ /* Invert the camera intrinsics/ */
+ Tracks normalized_tracks;
+ libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
+
+ /* keyframe selection. */
+ int keyframe1 = libmv_reconstruction_options->keyframe1,
+ keyframe2 = libmv_reconstruction_options->keyframe2;
+
+ if (libmv_reconstruction_options->select_keyframes) {
+ LG << "Using automatic keyframe selection";
+
+ update_callback.invoke(0, "Selecting keyframes");
+
+ selectTwoKeyframesBasedOnGRICAndVariance(tracks,
+ normalized_tracks,
+ *camera_intrinsics,
+ keyframe1,
+ keyframe2);
+
+ /* so keyframes in the interface would be updated */
+ libmv_reconstruction_options->keyframe1 = keyframe1;
+ libmv_reconstruction_options->keyframe2 = keyframe2;
+ }
+
+ /* Actual reconstruction. */
+ LG << "frames to init from: " << keyframe1 << " " << keyframe2;
+
+ libmv::vector<Marker> keyframe_markers =
+ normalized_tracks.MarkersForTracksInBothImages(keyframe1, keyframe2);
+
+ LG << "number of markers for init: " << keyframe_markers.size();
+
+ update_callback.invoke(0, "Initial reconstruction");
+
+ EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
+ EuclideanBundle(normalized_tracks, &reconstruction);
+ EuclideanCompleteReconstruction(normalized_tracks,
+ &reconstruction,
+ &update_callback);
+
+ /* Refinement/ */
+ if (libmv_reconstruction_options->refine_intrinsics) {
+ libmv_solveRefineIntrinsics(
+ tracks,
+ libmv_reconstruction_options->refine_intrinsics,
+ libmv::BUNDLE_NO_CONSTRAINTS,
+ progress_update_callback,
+ callback_customdata,
+ &reconstruction,
+ camera_intrinsics);
+ }
+
+ /* Set reconstruction scale to unity. */
+ EuclideanScaleToUnity(&reconstruction);
+
+ /* Finish reconstruction. */
+ finishReconstruction(tracks,
+ *camera_intrinsics,
+ libmv_reconstruction,
+ progress_update_callback,
+ callback_customdata);
+
+ return (libmv_Reconstruction *) libmv_reconstruction;
+}
+
+libmv_Reconstruction *libmv_solveModal(
+ const libmv_Tracks *libmv_tracks,
+ const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
+ const libmv_ReconstructionOptions *libmv_reconstruction_options,
+ reconstruct_progress_update_cb progress_update_callback,
+ void *callback_customdata) {
+ libmv_Reconstruction *libmv_reconstruction =
+ LIBMV_OBJECT_NEW(libmv_Reconstruction);
+
+ Tracks &tracks = *((Tracks *) libmv_tracks);
+ EuclideanReconstruction &reconstruction =
+ libmv_reconstruction->reconstruction;
+
+ ReconstructUpdateCallback update_callback =
+ ReconstructUpdateCallback(progress_update_callback,
+ callback_customdata);
+
+ /* Retrieve reconstruction options from C-API to libmv API. */
+ CameraIntrinsics *camera_intrinsics;
+ camera_intrinsics = libmv_reconstruction->intrinsics =
+ libmv_cameraIntrinsicsCreateFromOptions(
+ libmv_camera_intrinsics_options);
+
+ /* Invert the camera intrinsics. */
+ Tracks normalized_tracks;
+ libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
+
+ /* Actual reconstruction. */
+ ModalSolver(normalized_tracks, &reconstruction, &update_callback);
+
+ PolynomialCameraIntrinsics empty_intrinsics;
+ EuclideanBundleCommonIntrinsics(normalized_tracks,
+ libmv::BUNDLE_NO_INTRINSICS,
+ libmv::BUNDLE_NO_TRANSLATION,
+ &reconstruction,
+ &empty_intrinsics);
+
+ /* Refinement. */
+ if (libmv_reconstruction_options->refine_intrinsics) {
+ libmv_solveRefineIntrinsics(
+ tracks,
+ libmv_reconstruction_options->refine_intrinsics,
+ libmv::BUNDLE_NO_TRANSLATION,
+ progress_update_callback, callback_customdata,
+ &reconstruction,
+ camera_intrinsics);
+ }
+
+ /* Finish reconstruction. */
+ finishReconstruction(tracks,
+ *camera_intrinsics,
+ libmv_reconstruction,
+ progress_update_callback,
+ callback_customdata);
+
+ return (libmv_Reconstruction *) libmv_reconstruction;
+}
+
+void libmv_reconstructionDestroy(libmv_Reconstruction *libmv_reconstruction) {
+ LIBMV_OBJECT_DELETE(libmv_reconstruction->intrinsics, CameraIntrinsics);
+ LIBMV_OBJECT_DELETE(libmv_reconstruction, libmv_Reconstruction);
+}
+
+int libmv_reprojectionPointForTrack(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int track,
+ double pos[3]) {
+ const EuclideanReconstruction *reconstruction =
+ &libmv_reconstruction->reconstruction;
+ const EuclideanPoint *point =
+ reconstruction->PointForTrack(track);
+ if (point) {
+ pos[0] = point->X[0];
+ pos[1] = point->X[2];
+ pos[2] = point->X[1];
+ return 1;
+ }
+ return 0;
+}
+
+double libmv_reprojectionErrorForTrack(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int track) {
+ const EuclideanReconstruction *reconstruction =
+ &libmv_reconstruction->reconstruction;
+ const CameraIntrinsics *intrinsics = libmv_reconstruction->intrinsics;
+ libmv::vector<Marker> markers =
+ libmv_reconstruction->tracks.MarkersForTrack(track);
+
+ int num_reprojected = 0;
+ double total_error = 0.0;
+
+ for (int i = 0; i < markers.size(); ++i) {
+ double weight = markers[i].weight;
+ const EuclideanCamera *camera =
+ reconstruction->CameraForImage(markers[i].image);
+ const EuclideanPoint *point =
+ reconstruction->PointForTrack(markers[i].track);
+
+ if (!camera || !point || weight == 0.0) {
+ continue;
+ }
+
+ num_reprojected++;
+
+ Marker reprojected_marker =
+ libmv_projectMarker(*point, *camera, *intrinsics);
+ double ex = (reprojected_marker.x - markers[i].x) * weight;
+ double ey = (reprojected_marker.y - markers[i].y) * weight;
+
+ total_error += sqrt(ex * ex + ey * ey);
+ }
+
+ return total_error / num_reprojected;
+}
+
+double libmv_reprojectionErrorForImage(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int image) {
+ const EuclideanReconstruction *reconstruction =
+ &libmv_reconstruction->reconstruction;
+ const CameraIntrinsics *intrinsics = libmv_reconstruction->intrinsics;
+ libmv::vector<Marker> markers =
+ libmv_reconstruction->tracks.MarkersInImage(image);
+ const EuclideanCamera *camera = reconstruction->CameraForImage(image);
+ int num_reprojected = 0;
+ double total_error = 0.0;
+
+ if (!camera) {
+ return 0.0;
+ }
+
+ for (int i = 0; i < markers.size(); ++i) {
+ const EuclideanPoint *point =
+ reconstruction->PointForTrack(markers[i].track);
+
+ if (!point) {
+ continue;
+ }
+
+ num_reprojected++;
+
+ Marker reprojected_marker =
+ libmv_projectMarker(*point, *camera, *intrinsics);
+ double ex = (reprojected_marker.x - markers[i].x) * markers[i].weight;
+ double ey = (reprojected_marker.y - markers[i].y) * markers[i].weight;
+
+ total_error += sqrt(ex * ex + ey * ey);
+ }
+
+ return total_error / num_reprojected;
+}
+
+int libmv_reprojectionCameraForImage(
+ const libmv_Reconstruction *libmv_reconstruction,
+ int image,
+ double mat[4][4]) {
+ const EuclideanReconstruction *reconstruction =
+ &libmv_reconstruction->reconstruction;
+ const EuclideanCamera *camera =
+ reconstruction->CameraForImage(image);
+
+ if (camera) {
+ for (int j = 0; j < 3; ++j) {
+ for (int k = 0; k < 3; ++k) {
+ int l = k;
+
+ if (k == 1) {
+ l = 2;
+ } else if (k == 2) {
+ l = 1;
+ }
+
+ if (j == 2) {
+ mat[j][l] = -camera->R(j, k);
+ } else {
+ mat[j][l] = camera->R(j, k);
+ }
+ }
+ mat[j][3] = 0.0;
+ }
+
+ libmv::Vec3 optical_center = -camera->R.transpose() * camera->t;
+
+ mat[3][0] = optical_center(0);
+ mat[3][1] = optical_center(2);
+ mat[3][2] = optical_center(1);
+
+ mat[3][3] = 1.0;
+
+ return 1;
+ }
+
+ return 0;
+}
+
+double libmv_reprojectionError(
+ const libmv_Reconstruction *libmv_reconstruction) {
+ return libmv_reconstruction->error;
+}
+
+libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(
+ libmv_Reconstruction *libmv_reconstruction) {
+ return (libmv_CameraIntrinsics *) libmv_reconstruction->intrinsics;
+}
diff --git a/extern/libmv/intern/reconstruction.h b/extern/libmv/intern/reconstruction.h
new file mode 100644
index 00000000000..88e810b54aa
--- /dev/null
+++ b/extern/libmv/intern/reconstruction.h
@@ -0,0 +1,100 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_RECONSTRUCTION_H_
+#define LIBMV_C_API_RECONSTRUCTION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct libmv_Tracks;
+struct libmv_CameraIntrinsics;
+struct libmv_CameraIntrinsicsOptions;
+
+typedef struct libmv_Reconstruction libmv_Reconstruction;
+
+enum {
+ LIBMV_REFINE_FOCAL_LENGTH = (1 << 0),
+ LIBMV_REFINE_PRINCIPAL_POINT = (1 << 1),
+ LIBMV_REFINE_RADIAL_DISTORTION_K1 = (1 << 2),
+ LIBMV_REFINE_RADIAL_DISTORTION_K2 = (1 << 4),
+};
+
+typedef struct libmv_ReconstructionOptions {
+ int select_keyframes;
+ int keyframe1, keyframe2;
+ int refine_intrinsics;
+} libmv_ReconstructionOptions;
+
+typedef void (*reconstruct_progress_update_cb) (void* customdata,
+ double progress,
+ const char* message);
+
+libmv_Reconstruction* libmv_solveReconstruction(
+ const struct libmv_Tracks* libmv_tracks,
+ const struct libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ libmv_ReconstructionOptions* libmv_reconstruction_options,
+ reconstruct_progress_update_cb progress_update_callback,
+ void* callback_customdata);
+
+libmv_Reconstruction* libmv_solveModal(
+ const struct libmv_Tracks* libmv_tracks,
+ const struct libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ const libmv_ReconstructionOptions* libmv_reconstruction_options,
+ reconstruct_progress_update_cb progress_update_callback,
+ void* callback_customdata);
+
+void libmv_reconstructionDestroy(libmv_Reconstruction* libmv_reconstruction);
+
+int libmv_reprojectionPointForTrack(
+ const libmv_Reconstruction* libmv_reconstruction,
+ int track,
+ double pos[3]);
+
+double libmv_reprojectionErrorForTrack(
+ const libmv_Reconstruction* libmv_reconstruction,
+ int track);
+
+double libmv_reprojectionErrorForImage(
+ const libmv_Reconstruction* libmv_reconstruction,
+ int image);
+
+int libmv_reprojectionCameraForImage(
+ const libmv_Reconstruction* libmv_reconstruction,
+ int image,
+ double mat[4][4]);
+
+double libmv_reprojectionError(const libmv_Reconstruction* libmv_reconstruction);
+
+struct libmv_CameraIntrinsics* libmv_reconstructionExtractIntrinsics(
+ libmv_Reconstruction *libmv_Reconstruction);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_RECONSTRUCTION_H_
diff --git a/extern/libmv/intern/region.h b/extern/libmv/intern/region.h
new file mode 100644
index 00000000000..9f114bbad3b
--- /dev/null
+++ b/extern/libmv/intern/region.h
@@ -0,0 +1,43 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2014 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_REGION_H_
+#define LIBMV_C_API_REGION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_Region {
+ float min[2];
+ float max[2];
+} libmv_Region;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_REGION_H_
diff --git a/extern/libmv/intern/stub.cc b/extern/libmv/intern/stub.cc
new file mode 100644
index 00000000000..cd8bb8ab841
--- /dev/null
+++ b/extern/libmv/intern/stub.cc
@@ -0,0 +1,330 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "libmv-capi.h"
+
+#include <cstdlib>
+#include <cstring>
+
+/* ************ Logging ************ */
+
+void libmv_initLogging(const char * /*argv0*/) {
+}
+
+void libmv_startDebugLogging(void) {
+}
+
+void libmv_setLoggingVerbosity(int /*verbosity*/) {
+}
+
+/* ************ Planar tracker ************ */
+
+/* TrackRegion (new planar tracker) */
+int libmv_trackRegion(const libmv_TrackRegionOptions * /*options*/,
+ const float * /*image1*/,
+ int /*image1_width*/,
+ int /*image1_height*/,
+ const float * /*image2*/,
+ int /*image2_width*/,
+ int /*image2_height*/,
+ const double *x1,
+ const double *y1,
+ libmv_TrackRegionResult *result,
+ double *x2,
+ double *y2) {
+ /* Convert to doubles for the libmv api. The four corners and the center. */
+ for (int i = 0; i < 5; ++i) {
+ x2[i] = x1[i];
+ y2[i] = y1[i];
+ }
+
+ result->termination = -1;
+ result->termination_reason = "Built without libmv support";
+ result->correlation = 0.0;
+
+ return false;
+}
+
+void libmv_samplePlanarPatchFloat(const float * /*image*/,
+ int /*width*/,
+ int /*height*/,
+ int /*channels*/,
+ const double * /*xs*/,
+ const double * /*ys*/,
+ int /*num_samples_x*/,
+ int /*num_samples_y*/,
+ const float * /*mask*/,
+ float * /*patch*/,
+ double * /*warped_position_x*/,
+ double * /*warped_position_y*/) {
+ /* TODO(sergey): implement */
+}
+
+void libmv_samplePlanarPatchByte(const unsigned char * /*image*/,
+ int /*width*/,
+ int /*height*/,
+ int /*channels*/,
+ const double * /*xs*/,
+ const double * /*ys*/,
+ int /*num_samples_x*/, int /*num_samples_y*/,
+ const float * /*mask*/,
+ unsigned char * /*patch*/,
+ double * /*warped_position_x*/,
+ double * /*warped_position_y*/) {
+ /* TODO(sergey): implement */
+}
+
+/* ************ Tracks ************ */
+
+libmv_Tracks *libmv_tracksNew(void) {
+ return NULL;
+}
+
+void libmv_tracksInsert(libmv_Tracks * /*libmv_tracks*/,
+ int /*image*/,
+ int /*track*/,
+ double /*x*/,
+ double /*y*/,
+ double /*weight*/) {
+}
+
+void libmv_tracksDestroy(libmv_Tracks * /*libmv_tracks*/) {
+}
+
+/* ************ Reconstruction solver ************ */
+
+libmv_Reconstruction *libmv_solveReconstruction(
+ const libmv_Tracks * /*libmv_tracks*/,
+ const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/,
+ libmv_ReconstructionOptions * /*libmv_reconstruction_options*/,
+ reconstruct_progress_update_cb /*progress_update_callback*/,
+ void * /*callback_customdata*/) {
+ return NULL;
+}
+
+libmv_Reconstruction *libmv_solveModal(
+ const libmv_Tracks * /*libmv_tracks*/,
+ const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/,
+ const libmv_ReconstructionOptions * /*libmv_reconstruction_options*/,
+ reconstruct_progress_update_cb /*progress_update_callback*/,
+ void * /*callback_customdata*/) {
+ return NULL;
+}
+
+int libmv_reprojectionPointForTrack(
+ const libmv_Reconstruction * /*libmv_reconstruction*/,
+ int /*track*/,
+ double /*pos*/[3]) {
+ return 0;
+}
+
+double libmv_reprojectionErrorForTrack(
+ const libmv_Reconstruction * /*libmv_reconstruction*/,
+ int /*track*/) {
+ return 0.0;
+}
+
+double libmv_reprojectionErrorForImage(
+ const libmv_Reconstruction * /*libmv_reconstruction*/,
+ int /*image*/) {
+ return 0.0;
+}
+
+int libmv_reprojectionCameraForImage(
+ const libmv_Reconstruction * /*libmv_reconstruction*/,
+ int /*image*/,
+ double /*mat*/[4][4]) {
+ return 0;
+}
+
+double libmv_reprojectionError(
+ const libmv_Reconstruction * /*libmv_reconstruction*/) {
+ return 0.0;
+}
+
+void libmv_reconstructionDestroy(
+ struct libmv_Reconstruction * /*libmv_reconstruction*/) {
+}
+
+/* ************ Feature detector ************ */
+
+libmv_Features *libmv_detectFeaturesByte(const unsigned char */*image_buffer*/,
+ int /*width*/,
+ int /*height*/,
+ int /*channels*/,
+ libmv_DetectOptions */*options*/) {
+ return NULL;
+}
+
+struct libmv_Features *libmv_detectFeaturesFloat(
+ const float */*image_buffer*/,
+ int /*width*/,
+ int /*height*/,
+ int /*channels*/,
+ libmv_DetectOptions */*options*/) {
+ return NULL;
+}
+
+int libmv_countFeatures(const libmv_Features * /*libmv_features*/) {
+ return 0;
+}
+
+void libmv_getFeature(const libmv_Features * /*libmv_features*/,
+ int /*number*/,
+ double *x,
+ double *y,
+ double *score,
+ double *size) {
+ *x = 0.0;
+ *y = 0.0;
+ *score = 0.0;
+ *size = 0.0;
+}
+
+void libmv_featuresDestroy(struct libmv_Features * /*libmv_features*/) {
+}
+
+/* ************ Camera intrinsics ************ */
+
+libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(
+ libmv_Reconstruction * /*libmv_reconstruction*/) {
+ return NULL;
+}
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
+ const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/) {
+ return NULL;
+}
+
+libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
+ const libmv_CameraIntrinsics * /*libmvIntrinsics*/) {
+ return NULL;
+}
+
+void libmv_cameraIntrinsicsDestroy(
+ libmv_CameraIntrinsics * /*libmvIntrinsics*/) {
+}
+
+void libmv_cameraIntrinsicsUpdate(
+ const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/,
+ libmv_CameraIntrinsics * /*libmv_intrinsics*/) {
+}
+
+void libmv_cameraIntrinsicsSetThreads(
+ libmv_CameraIntrinsics * /*libmv_intrinsics*/,
+ int /*threads*/) {
+}
+
+void libmv_cameraIntrinsicsExtractOptions(
+ const libmv_CameraIntrinsics */*libmv_intrinsics*/,
+ libmv_CameraIntrinsicsOptions *camera_intrinsics_options) {
+ memset(camera_intrinsics_options, 0, sizeof(libmv_CameraIntrinsicsOptions));
+ camera_intrinsics_options->focal_length = 1.0;
+}
+
+void libmv_cameraIntrinsicsUndistortByte(
+ const libmv_CameraIntrinsics * /*libmv_intrinsics*/,
+ const unsigned char *source_image,
+ int width, int height,
+ float overscan, int channels,
+ unsigned char *destination_image) {
+ memcpy(destination_image, source_image,
+ channels * width * height * sizeof(unsigned char));
+}
+
+void libmv_cameraIntrinsicsUndistortFloat(
+ const libmv_CameraIntrinsics* /*libmv_intrinsics*/,
+ const float* source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ float* destination_image) {
+ memcpy(destination_image, source_image,
+ channels * width * height * sizeof(float));
+}
+
+void libmv_cameraIntrinsicsDistortByte(
+ const struct libmv_CameraIntrinsics* /*libmv_intrinsics*/,
+ const unsigned char *source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ unsigned char *destination_image) {
+ memcpy(destination_image, source_image,
+ channels * width * height * sizeof(unsigned char));
+}
+
+void libmv_cameraIntrinsicsDistortFloat(
+ const libmv_CameraIntrinsics* /*libmv_intrinsics*/,
+ float* source_image,
+ int width,
+ int height,
+ float overscan,
+ int channels,
+ float* destination_image) {
+ memcpy(destination_image, source_image,
+ channels * width * height * sizeof(float));
+}
+
+/* ************ utils ************ */
+
+void libmv_cameraIntrinsicsApply(
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ double x,
+ double y,
+ double* x1,
+ double* y1) {
+ double focal_length = libmv_camera_intrinsics_options->focal_length;
+ double principal_x = libmv_camera_intrinsics_options->principal_point_x;
+ double principal_y = libmv_camera_intrinsics_options->principal_point_y;
+ *x1 = x * focal_length + principal_x;
+ *y1 = y * focal_length + principal_y;
+}
+
+void libmv_cameraIntrinsicsInvert(
+ const libmv_CameraIntrinsicsOptions* libmv_camera_intrinsics_options,
+ double x,
+ double y,
+ double* x1,
+ double* y1) {
+ double focal_length = libmv_camera_intrinsics_options->focal_length;
+ double principal_x = libmv_camera_intrinsics_options->principal_point_x;
+ double principal_y = libmv_camera_intrinsics_options->principal_point_y;
+ *x1 = (x - principal_x) / focal_length;
+ *y1 = (y - principal_y) / focal_length;
+}
+
+void libmv_homography2DFromCorrespondencesEuc(/* const */ double (*x1)[2],
+ /* const */ double (*x2)[2],
+ int num_points,
+ double H[3][3]) {
+ memset(H, 0, sizeof(double[3][3]));
+ H[0][0] = 1.0f;
+ H[1][1] = 1.0f;
+ H[2][2] = 1.0f;
+}
diff --git a/extern/libmv/intern/track_region.cc b/extern/libmv/intern/track_region.cc
new file mode 100644
index 00000000000..24fbc78c1a1
--- /dev/null
+++ b/extern/libmv/intern/track_region.cc
@@ -0,0 +1,177 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/track_region.h"
+#include "intern/image.h"
+#include "intern/utildefines.h"
+#include "libmv/image/image.h"
+#include "libmv/tracking/track_region.h"
+
+/* define this to generate PNG images with content of search areas
+ tracking between which failed */
+#undef DUMP_FAILURE
+
+/* define this to generate PNG images with content of search areas
+ on every itteration of tracking */
+#undef DUMP_ALWAYS
+
+using libmv::FloatImage;
+using libmv::TrackRegionOptions;
+using libmv::TrackRegionResult;
+using libmv::TrackRegion;
+
+void libmv_configureTrackRegionOptions(
+ const libmv_TrackRegionOptions& options,
+ TrackRegionOptions* track_region_options) {
+ switch (options.motion_model) {
+#define LIBMV_CONVERT(the_model) \
+ case TrackRegionOptions::the_model: \
+ track_region_options->mode = TrackRegionOptions::the_model; \
+ break;
+ LIBMV_CONVERT(TRANSLATION)
+ LIBMV_CONVERT(TRANSLATION_ROTATION)
+ LIBMV_CONVERT(TRANSLATION_SCALE)
+ LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE)
+ LIBMV_CONVERT(AFFINE)
+ LIBMV_CONVERT(HOMOGRAPHY)
+#undef LIBMV_CONVERT
+ }
+
+ track_region_options->minimum_correlation = options.minimum_correlation;
+ track_region_options->max_iterations = options.num_iterations;
+ track_region_options->sigma = options.sigma;
+ track_region_options->num_extra_points = 1;
+ track_region_options->image1_mask = NULL;
+ track_region_options->use_brute_initialization = options.use_brute;
+ /* TODO(keir): This will make some cases better, but may be a regression until
+ * the motion model is in. Since this is on trunk, enable it for now.
+ *
+ * TODO(sergey): This gives much worse results on mango footage (see 04_2e)
+ * so disabling for now for until proper prediction model is landed.
+ *
+ * The thing is, currently blender sends input coordinates as the guess to
+ * region tracker and in case of fast motion such an early out ruins the track.
+ */
+ track_region_options->attempt_refine_before_brute = false;
+ track_region_options->use_normalized_intensities = options.use_normalization;
+}
+
+void libmv_regionTrackergetResult(const TrackRegionResult& track_region_result,
+ libmv_TrackRegionResult* result) {
+ result->termination = (int) track_region_result.termination;
+ result->termination_reason = "";
+ result->correlation = track_region_result.correlation;
+}
+
+int libmv_trackRegion(const libmv_TrackRegionOptions* options,
+ const float* image1,
+ int image1_width,
+ int image1_height,
+ const float* image2,
+ int image2_width,
+ int image2_height,
+ const double* x1,
+ const double* y1,
+ libmv_TrackRegionResult* result,
+ double* x2,
+ double* y2) {
+ double xx1[5], yy1[5];
+ double xx2[5], yy2[5];
+ bool tracking_result = false;
+
+ // Convert to doubles for the libmv api. The four corners and the center.
+ for (int i = 0; i < 5; ++i) {
+ xx1[i] = x1[i];
+ yy1[i] = y1[i];
+ xx2[i] = x2[i];
+ yy2[i] = y2[i];
+ }
+
+ TrackRegionOptions track_region_options;
+ FloatImage image1_mask;
+
+ libmv_configureTrackRegionOptions(*options, &track_region_options);
+ if (options->image1_mask) {
+ libmv_floatBufferToFloatImage(options->image1_mask,
+ image1_width,
+ image1_height,
+ 1,
+ &image1_mask);
+
+ track_region_options.image1_mask = &image1_mask;
+ }
+
+ // Convert from raw float buffers to libmv's FloatImage.
+ FloatImage old_patch, new_patch;
+ libmv_floatBufferToFloatImage(image1,
+ image1_width,
+ image1_height,
+ 1,
+ &old_patch);
+ libmv_floatBufferToFloatImage(image2,
+ image2_width,
+ image2_height,
+ 1,
+ &new_patch);
+
+ TrackRegionResult track_region_result;
+ TrackRegion(old_patch, new_patch,
+ xx1, yy1,
+ track_region_options,
+ xx2, yy2,
+ &track_region_result);
+
+ // Convert to floats for the blender api.
+ for (int i = 0; i < 5; ++i) {
+ x2[i] = xx2[i];
+ y2[i] = yy2[i];
+ }
+
+ // TODO(keir): Update the termination string with failure details.
+ if (track_region_result.termination == TrackRegionResult::CONVERGENCE ||
+ track_region_result.termination == TrackRegionResult::NO_CONVERGENCE) {
+ tracking_result = true;
+ }
+
+ // Debug dump of patches.
+#if defined(DUMP_FAILURE) || defined(DUMP_ALWAYS)
+ bool need_dump = !tracking_result;
+
+# ifdef DUMP_ALWAYS
+ need_dump = true;
+# endif
+
+ if (need_dump) {
+ libmv_saveImage(old_patch, "old_patch", x1[4], y1[4]);
+ libmv_saveImage(new_patch, "new_patch", x2[4], y2[4]);
+ if (options->image1_mask) {
+ libmv_saveImage(image1_mask, "mask", x2[4], y2[4]);
+ }
+ }
+#endif
+
+ return tracking_result;
+}
diff --git a/extern/libmv/intern/track_region.h b/extern/libmv/intern/track_region.h
new file mode 100644
index 00000000000..7ed3e443e40
--- /dev/null
+++ b/extern/libmv/intern/track_region.h
@@ -0,0 +1,81 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_TRACK_REGION_H_
+#define LIBMV_C_API_TRACK_REGION_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_TrackRegionOptions {
+ int motion_model;
+ int num_iterations;
+ int use_brute;
+ int use_normalization;
+ double minimum_correlation;
+ double sigma;
+ float *image1_mask;
+} libmv_TrackRegionOptions;
+
+typedef struct libmv_TrackRegionResult {
+ int termination;
+ const char* termination_reason;
+ double correlation;
+} libmv_TrackRegionResult;
+
+#ifdef __cplusplus
+namespace libmv {
+ struct TrackRegionOptions;
+ struct TrackRegionResult;
+}
+void libmv_configureTrackRegionOptions(
+ const libmv_TrackRegionOptions& options,
+ libmv::TrackRegionOptions* track_region_options);
+
+void libmv_regionTrackergetResult(
+ const libmv::TrackRegionResult& track_region_result,
+ libmv_TrackRegionResult* result);
+#endif
+
+int libmv_trackRegion(const libmv_TrackRegionOptions* options,
+ const float* image1,
+ int image1_width,
+ int image1_height,
+ const float* image2,
+ int image2_width,
+ int image2_height,
+ const double* x1,
+ const double* y1,
+ libmv_TrackRegionResult* result,
+ double* x2,
+ double* y2);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_PLANAR_TRACKER_H_
diff --git a/extern/libmv/intern/tracks.cc b/extern/libmv/intern/tracks.cc
new file mode 100644
index 00000000000..9b032b0760a
--- /dev/null
+++ b/extern/libmv/intern/tracks.cc
@@ -0,0 +1,52 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "intern/tracks.h"
+#include "intern/utildefines.h"
+
+#include "libmv/simple_pipeline/tracks.h"
+
+using libmv::Marker;
+using libmv::Tracks;
+
+libmv_Tracks* libmv_tracksNew(void) {
+ Tracks* tracks = LIBMV_OBJECT_NEW(Tracks);
+
+ return (libmv_Tracks*) tracks;
+}
+
+void libmv_tracksDestroy(libmv_Tracks* libmv_tracks) {
+ LIBMV_OBJECT_DELETE(libmv_tracks, Tracks);
+}
+
+void libmv_tracksInsert(libmv_Tracks *libmv_tracks,
+ int image,
+ int track,
+ double x,
+ double y,
+ double weight) {
+ ((Tracks *) libmv_tracks)->Insert(image, track, x, y, weight);
+}
diff --git a/extern/libmv/intern/tracks.h b/extern/libmv/intern/tracks.h
new file mode 100644
index 00000000000..79f6cc99579
--- /dev/null
+++ b/extern/libmv/intern/tracks.h
@@ -0,0 +1,51 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2011 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef LIBMV_C_API_TRACKS_H_
+#define LIBMV_C_API_TRACKS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct libmv_Tracks libmv_Tracks;
+
+libmv_Tracks* libmv_tracksNew(void);
+
+void libmv_tracksDestroy(libmv_Tracks* libmv_tracks);
+
+void libmv_tracksInsert(libmv_Tracks* libmv_tracks,
+ int image,
+ int track,
+ double x,
+ double y,
+ double weight);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // LIBMV_C_API_TRACKS_H_
diff --git a/extern/libmv/libmv-capi_intern.h b/extern/libmv/intern/utildefines.h
index 90087c52a6c..7366b242cf7 100644
--- a/extern/libmv/libmv-capi_intern.h
+++ b/extern/libmv/intern/utildefines.h
@@ -23,8 +23,8 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef LIBMV_C_API_INTERN_H
-#define LIBMV_C_API_INTERN_H
+#ifndef LIBMV_C_API_UTILDEFINES_H_
+#define LIBMV_C_API_UTILDEFINES_H_
#if defined(_MSC_VER)
# define __func__ __FUNCTION__
@@ -36,24 +36,27 @@
# define LIBMV_OBJECT_NEW OBJECT_GUARDED_NEW
# define LIBMV_OBJECT_DELETE OBJECT_GUARDED_DELETE
# define LIBMV_OBJECT_DELETE OBJECT_GUARDED_DELETE
-# define LIBMV_STRUCT_NEW(type, count) (type*)MEM_mallocN(sizeof(type) * count, __func__)
+# define LIBMV_STRUCT_NEW(type, count) \
+ (type*)MEM_mallocN(sizeof(type) * count, __func__)
# define LIBMV_STRUCT_DELETE(what) MEM_freeN(what)
#else
// Need this to keep libmv-capi potentially standalone.
# if defined __GNUC__ || defined __sun
# define LIBMV_OBJECT_NEW(type, args ...) \
- new(malloc(sizeof(type))) type(args)
+ new(malloc(sizeof(type))) type(args)
# else
# define LIBMV_OBJECT_NEW(type, ...) \
- new(malloc(sizeof(type))) type(__VA_ARGS__)
+ new(malloc(sizeof(type))) type(__VA_ARGS__)
#endif
# define LIBMV_OBJECT_DELETE(what, type) \
- { if(what) { \
- ((type*)(what))->~type(); \
- free(what); \
- } } (void)0
+ { \
+ if (what) { \
+ ((type*)(what))->~type(); \
+ free(what); \
+ } \
+ } (void)0
# define LIBMV_STRUCT_NEW(type, count) (type*)malloc(sizeof(type) * count)
# define LIBMV_STRUCT_DELETE(what) { if (what) free(what); } (void)0
#endif
-#endif // LIBMV_C_API_INTERN_H
+#endif // LIBMV_C_API_UTILDEFINES_H_
diff --git a/extern/libmv/libmv-capi.cc b/extern/libmv/libmv-capi.cc
deleted file mode 100644
index 82143d50fbf..00000000000
--- a/extern/libmv/libmv-capi.cc
+++ /dev/null
@@ -1,1185 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2011 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation,
- * Sergey Sharybin
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifdef WITH_LIBMV
-
-/* define this to generate PNG images with content of search areas
- tracking between which failed */
-#undef DUMP_FAILURE
-
-/* define this to generate PNG images with content of search areas
- on every itteration of tracking */
-#undef DUMP_ALWAYS
-
-#include "libmv-capi.h"
-#include "libmv-util.h"
-
-#include <cassert>
-
-#include "libmv-capi_intern.h"
-#include "libmv/logging/logging.h"
-#include "libmv/multiview/homography.h"
-#include "libmv/tracking/track_region.h"
-#include "libmv/simple_pipeline/callbacks.h"
-#include "libmv/simple_pipeline/tracks.h"
-#include "libmv/simple_pipeline/initialize_reconstruction.h"
-#include "libmv/simple_pipeline/bundle.h"
-#include "libmv/simple_pipeline/detect.h"
-#include "libmv/simple_pipeline/pipeline.h"
-#include "libmv/simple_pipeline/camera_intrinsics.h"
-#include "libmv/simple_pipeline/modal_solver.h"
-#include "libmv/simple_pipeline/reconstruction_scale.h"
-#include "libmv/simple_pipeline/keyframe_selection.h"
-
-#ifdef _MSC_VER
-# define snprintf _snprintf
-#endif
-
-using libmv::CameraIntrinsics;
-using libmv::DetectOptions;
-using libmv::DivisionCameraIntrinsics;
-using libmv::EuclideanCamera;
-using libmv::EuclideanPoint;
-using libmv::EuclideanReconstruction;
-using libmv::EuclideanScaleToUnity;
-using libmv::Feature;
-using libmv::FloatImage;
-using libmv::Marker;
-using libmv::PolynomialCameraIntrinsics;
-using libmv::ProgressUpdateCallback;
-using libmv::Tracks;
-using libmv::TrackRegionOptions;
-using libmv::TrackRegionResult;
-
-using libmv::Detect;
-using libmv::EuclideanBundle;
-using libmv::EuclideanCompleteReconstruction;
-using libmv::EuclideanReconstructTwoFrames;
-using libmv::EuclideanReprojectionError;
-using libmv::TrackRegion;
-using libmv::SamplePlanarPatch;
-
-typedef struct libmv_Tracks libmv_Tracks;
-typedef struct libmv_Reconstruction libmv_Reconstruction;
-typedef struct libmv_Features libmv_Features;
-typedef struct libmv_CameraIntrinsics libmv_CameraIntrinsics;
-
-struct libmv_Reconstruction {
- EuclideanReconstruction reconstruction;
-
- /* used for per-track average error calculation after reconstruction */
- Tracks tracks;
- CameraIntrinsics *intrinsics;
-
- double error;
-};
-
-struct libmv_Features {
- int count;
- Feature *features;
-};
-
-/* ************ Logging ************ */
-
-void libmv_initLogging(const char *argv0)
-{
- /* Make it so FATAL messages are always print into console */
- char severity_fatal[32];
- snprintf(severity_fatal, sizeof(severity_fatal), "%d",
- google::GLOG_FATAL);
-
- google::InitGoogleLogging(argv0);
- google::SetCommandLineOption("logtostderr", "1");
- google::SetCommandLineOption("v", "0");
- google::SetCommandLineOption("stderrthreshold", severity_fatal);
- google::SetCommandLineOption("minloglevel", severity_fatal);
-}
-
-void libmv_startDebugLogging(void)
-{
- google::SetCommandLineOption("logtostderr", "1");
- google::SetCommandLineOption("v", "2");
- google::SetCommandLineOption("stderrthreshold", "1");
- google::SetCommandLineOption("minloglevel", "0");
-}
-
-void libmv_setLoggingVerbosity(int verbosity)
-{
- char val[10];
- snprintf(val, sizeof(val), "%d", verbosity);
-
- google::SetCommandLineOption("v", val);
-}
-
-/* ************ Planar tracker ************ */
-
-/* TrackRegion */
-int libmv_trackRegion(const libmv_TrackRegionOptions *options,
- const float *image1, int image1_width, int image1_height,
- const float *image2, int image2_width, int image2_height,
- const double *x1, const double *y1,
- libmv_TrackRegionResult *result,
- double *x2, double *y2)
-{
- double xx1[5], yy1[5];
- double xx2[5], yy2[5];
- bool tracking_result = false;
-
- /* Convert to doubles for the libmv api. The four corners and the center. */
- for (int i = 0; i < 5; ++i) {
- xx1[i] = x1[i];
- yy1[i] = y1[i];
- xx2[i] = x2[i];
- yy2[i] = y2[i];
- }
-
- TrackRegionOptions track_region_options;
- FloatImage image1_mask;
-
- switch (options->motion_model) {
-#define LIBMV_CONVERT(the_model) \
- case TrackRegionOptions::the_model: \
- track_region_options.mode = TrackRegionOptions::the_model; \
- break;
- LIBMV_CONVERT(TRANSLATION)
- LIBMV_CONVERT(TRANSLATION_ROTATION)
- LIBMV_CONVERT(TRANSLATION_SCALE)
- LIBMV_CONVERT(TRANSLATION_ROTATION_SCALE)
- LIBMV_CONVERT(AFFINE)
- LIBMV_CONVERT(HOMOGRAPHY)
-#undef LIBMV_CONVERT
- }
-
- track_region_options.minimum_correlation = options->minimum_correlation;
- track_region_options.max_iterations = options->num_iterations;
- track_region_options.sigma = options->sigma;
- track_region_options.num_extra_points = 1;
- track_region_options.image1_mask = NULL;
- track_region_options.use_brute_initialization = options->use_brute;
- /* TODO(keir): This will make some cases better, but may be a regression until
- * the motion model is in. Since this is on trunk, enable it for now.
- *
- * TODO(sergey): This gives much worse results on mango footage (see 04_2e)
- * so disabling for now for until proper prediction model is landed.
- *
- * The thing is, currently blender sends input coordinates as the guess to
- * region tracker and in case of fast motion such an early out ruins the track.
- */
- track_region_options.attempt_refine_before_brute = false;
- track_region_options.use_normalized_intensities = options->use_normalization;
-
- if (options->image1_mask) {
- libmv_floatBufferToImage(options->image1_mask,
- image1_width, image1_height, 1,
- &image1_mask);
-
- track_region_options.image1_mask = &image1_mask;
- }
-
- /* Convert from raw float buffers to libmv's FloatImage. */
- FloatImage old_patch, new_patch;
- libmv_floatBufferToImage(image1,
- image1_width, image1_height, 1,
- &old_patch);
- libmv_floatBufferToImage(image2,
- image2_width, image2_height, 1,
- &new_patch);
-
- TrackRegionResult track_region_result;
- TrackRegion(old_patch, new_patch,
- xx1, yy1,
- track_region_options,
- xx2, yy2,
- &track_region_result);
-
- /* Convert to floats for the blender api. */
- for (int i = 0; i < 5; ++i) {
- x2[i] = xx2[i];
- y2[i] = yy2[i];
- }
-
- /* TODO(keir): Update the termination string with failure details. */
- if (track_region_result.termination == TrackRegionResult::CONVERGENCE ||
- track_region_result.termination == TrackRegionResult::NO_CONVERGENCE)
- {
- tracking_result = true;
- }
-
- /* Debug dump of patches. */
-#if defined(DUMP_FAILURE) || defined(DUMP_ALWAYS)
- {
- bool need_dump = !tracking_result;
-
-# ifdef DUMP_ALWAYS
- need_dump = true;
-# endif
-
- if (need_dump) {
- libmv_saveImage(old_patch, "old_patch", x1[4], y1[4]);
- libmv_saveImage(new_patch, "new_patch", x2[4], y2[4]);
-
- if (options->image1_mask) {
- libmv_saveImage(image1_mask, "mask", x2[4], y2[4]);
- }
- }
- }
-#endif
-
- return tracking_result;
-}
-
-void libmv_samplePlanarPatch(const float *image,
- int width, int height, int channels,
- const double *xs, const double *ys,
- int num_samples_x, int num_samples_y,
- const float *mask,
- float *patch,
- double *warped_position_x,
- double *warped_position_y)
-{
- FloatImage libmv_image, libmv_patch, libmv_mask;
- FloatImage *libmv_mask_for_sample = NULL;
-
- libmv_floatBufferToImage(image, width, height, channels, &libmv_image);
-
- if (mask) {
- libmv_floatBufferToImage(mask, width, height, 1, &libmv_mask);
-
- libmv_mask_for_sample = &libmv_mask;
- }
-
- SamplePlanarPatch(libmv_image,
- xs, ys,
- num_samples_x, num_samples_y,
- libmv_mask_for_sample,
- &libmv_patch,
- warped_position_x,
- warped_position_y);
-
- libmv_imageToFloatBuffer(libmv_patch, patch);
-}
-
- void libmv_samplePlanarPatchByte(const unsigned char *image,
- int width, int height, int channels,
- const double *xs, const double *ys,
- int num_samples_x, int num_samples_y,
- const float *mask,
- unsigned char *patch,
- double *warped_position_x, double *warped_position_y)
-{
- libmv::FloatImage libmv_image, libmv_patch, libmv_mask;
- libmv::FloatImage *libmv_mask_for_sample = NULL;
-
- libmv_byteBufferToImage(image, width, height, channels, &libmv_image);
-
- if (mask) {
- libmv_floatBufferToImage(mask, width, height, 1, &libmv_mask);
-
- libmv_mask_for_sample = &libmv_mask;
- }
-
- libmv::SamplePlanarPatch(libmv_image, xs, ys,
- num_samples_x, num_samples_y,
- libmv_mask_for_sample,
- &libmv_patch,
- warped_position_x,
- warped_position_y);
-
- libmv_imageToByteBuffer(libmv_patch, patch);
-}
-
-/* ************ Tracks ************ */
-
-libmv_Tracks *libmv_tracksNew(void)
-{
- Tracks *libmv_tracks = LIBMV_OBJECT_NEW(Tracks);
-
- return (libmv_Tracks *) libmv_tracks;
-}
-
-void libmv_tracksDestroy(libmv_Tracks *libmv_tracks)
-{
- LIBMV_OBJECT_DELETE(libmv_tracks, Tracks);
-}
-
-void libmv_tracksInsert(libmv_Tracks *libmv_tracks,
- int image, int track,
- double x, double y,
- double weight)
-{
- ((Tracks *) libmv_tracks)->Insert(image, track, x, y, weight);
-}
-
-/* ************ Reconstruction ************ */
-
-namespace {
-
-class ReconstructUpdateCallback : public ProgressUpdateCallback {
-public:
- ReconstructUpdateCallback(
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata)
- {
- progress_update_callback_ = progress_update_callback;
- callback_customdata_ = callback_customdata;
- }
-
- void invoke(double progress, const char *message)
- {
- if (progress_update_callback_) {
- progress_update_callback_(callback_customdata_, progress, message);
- }
- }
-protected:
- reconstruct_progress_update_cb progress_update_callback_;
- void *callback_customdata_;
-};
-
-void libmv_solveRefineIntrinsics(
- const Tracks &tracks,
- const int refine_intrinsics,
- const int bundle_constraints,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata,
- EuclideanReconstruction *reconstruction,
- CameraIntrinsics *intrinsics)
-{
- /* only a few combinations are supported but trust the caller */
- int bundle_intrinsics = 0;
-
- if (refine_intrinsics & LIBMV_REFINE_FOCAL_LENGTH) {
- bundle_intrinsics |= libmv::BUNDLE_FOCAL_LENGTH;
- }
- if (refine_intrinsics & LIBMV_REFINE_PRINCIPAL_POINT) {
- bundle_intrinsics |= libmv::BUNDLE_PRINCIPAL_POINT;
- }
- if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K1) {
- bundle_intrinsics |= libmv::BUNDLE_RADIAL_K1;
- }
- if (refine_intrinsics & LIBMV_REFINE_RADIAL_DISTORTION_K2) {
- bundle_intrinsics |= libmv::BUNDLE_RADIAL_K2;
- }
-
- progress_update_callback(callback_customdata, 1.0, "Refining solution");
-
- EuclideanBundleCommonIntrinsics(tracks,
- bundle_intrinsics,
- bundle_constraints,
- reconstruction,
- intrinsics);
-}
-
-void finishReconstruction(
- const Tracks &tracks,
- const CameraIntrinsics &camera_intrinsics,
- libmv_Reconstruction *libmv_reconstruction,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata)
-{
- EuclideanReconstruction &reconstruction =
- libmv_reconstruction->reconstruction;
-
- /* reprojection error calculation */
- progress_update_callback(callback_customdata, 1.0, "Finishing solution");
- libmv_reconstruction->tracks = tracks;
- libmv_reconstruction->error = EuclideanReprojectionError(tracks,
- reconstruction,
- camera_intrinsics);
-}
-
-bool selectTwoKeyframesBasedOnGRICAndVariance(
- Tracks &tracks,
- Tracks &normalized_tracks,
- CameraIntrinsics &camera_intrinsics,
- int &keyframe1,
- int &keyframe2)
-{
- libmv::vector<int> keyframes;
-
- /* Get list of all keyframe candidates first. */
- SelectKeyframesBasedOnGRICAndVariance(normalized_tracks,
- camera_intrinsics,
- keyframes);
-
- if (keyframes.size() < 2) {
- LG << "Not enough keyframes detected by GRIC";
- return false;
- }
- else if (keyframes.size() == 2) {
- keyframe1 = keyframes[0];
- keyframe2 = keyframes[1];
- return true;
- }
-
- /* Now choose two keyframes with minimal reprojection error after initial
- * reconstruction choose keyframes with the least reprojection error after
- * solving from two candidate keyframes.
- *
- * In fact, currently libmv returns single pair only, so this code will
- * not actually run. But in the future this could change, so let's stay
- * prepared.
- */
- int previous_keyframe = keyframes[0];
- double best_error = std::numeric_limits<double>::max();
- for (int i = 1; i < keyframes.size(); i++) {
- EuclideanReconstruction reconstruction;
- int current_keyframe = keyframes[i];
-
- libmv::vector<Marker> keyframe_markers =
- normalized_tracks.MarkersForTracksInBothImages(previous_keyframe,
- current_keyframe);
-
- Tracks keyframe_tracks(keyframe_markers);
-
- /* get a solution from two keyframes only */
- EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
- EuclideanBundle(keyframe_tracks, &reconstruction);
- EuclideanCompleteReconstruction(keyframe_tracks,
- &reconstruction,
- NULL);
-
- double current_error = EuclideanReprojectionError(tracks,
- reconstruction,
- camera_intrinsics);
-
- LG << "Error between " << previous_keyframe
- << " and " << current_keyframe
- << ": " << current_error;
-
- if (current_error < best_error) {
- best_error = current_error;
- keyframe1 = previous_keyframe;
- keyframe2 = current_keyframe;
- }
-
- previous_keyframe = current_keyframe;
- }
-
- return true;
-}
-
-} // namespace
-
-libmv_Reconstruction *libmv_solveReconstruction(
- const libmv_Tracks *libmv_tracks,
- const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- libmv_ReconstructionOptions *libmv_reconstruction_options,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata)
-{
- libmv_Reconstruction *libmv_reconstruction =
- LIBMV_OBJECT_NEW(libmv_Reconstruction);
-
- Tracks &tracks = *((Tracks *) libmv_tracks);
- EuclideanReconstruction &reconstruction =
- libmv_reconstruction->reconstruction;
-
- ReconstructUpdateCallback update_callback =
- ReconstructUpdateCallback(progress_update_callback,
- callback_customdata);
-
- /* Retrieve reconstruction options from C-API to libmv API */
- CameraIntrinsics *camera_intrinsics;
- camera_intrinsics = libmv_reconstruction->intrinsics =
- libmv_cameraIntrinsicsCreateFromOptions(
- libmv_camera_intrinsics_options);
-
- /* Invert the camera intrinsics */
- Tracks normalized_tracks;
- libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
-
- /* keyframe selection */
- int keyframe1 = libmv_reconstruction_options->keyframe1,
- keyframe2 = libmv_reconstruction_options->keyframe2;
-
- if (libmv_reconstruction_options->select_keyframes) {
- LG << "Using automatic keyframe selection";
-
- update_callback.invoke(0, "Selecting keyframes");
-
- selectTwoKeyframesBasedOnGRICAndVariance(tracks,
- normalized_tracks,
- *camera_intrinsics,
- keyframe1,
- keyframe2);
-
- /* so keyframes in the interface would be updated */
- libmv_reconstruction_options->keyframe1 = keyframe1;
- libmv_reconstruction_options->keyframe2 = keyframe2;
- }
-
- /* actual reconstruction */
- LG << "frames to init from: " << keyframe1 << " " << keyframe2;
-
- libmv::vector<Marker> keyframe_markers =
- normalized_tracks.MarkersForTracksInBothImages(keyframe1, keyframe2);
-
- LG << "number of markers for init: " << keyframe_markers.size();
-
- update_callback.invoke(0, "Initial reconstruction");
-
- EuclideanReconstructTwoFrames(keyframe_markers, &reconstruction);
- EuclideanBundle(normalized_tracks, &reconstruction);
- EuclideanCompleteReconstruction(normalized_tracks,
- &reconstruction,
- &update_callback);
-
- /* refinement */
- if (libmv_reconstruction_options->refine_intrinsics) {
- libmv_solveRefineIntrinsics(
- tracks,
- libmv_reconstruction_options->refine_intrinsics,
- libmv::BUNDLE_NO_CONSTRAINTS,
- progress_update_callback,
- callback_customdata,
- &reconstruction,
- camera_intrinsics);
- }
-
- /* set reconstruction scale to unity */
- EuclideanScaleToUnity(&reconstruction);
-
- /* finish reconstruction */
- finishReconstruction(tracks,
- *camera_intrinsics,
- libmv_reconstruction,
- progress_update_callback,
- callback_customdata);
-
- return (libmv_Reconstruction *) libmv_reconstruction;
-}
-
-libmv_Reconstruction *libmv_solveModal(
- const libmv_Tracks *libmv_tracks,
- const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- const libmv_ReconstructionOptions *libmv_reconstruction_options,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata)
-{
- libmv_Reconstruction *libmv_reconstruction =
- LIBMV_OBJECT_NEW(libmv_Reconstruction);
-
- Tracks &tracks = *((Tracks *) libmv_tracks);
- EuclideanReconstruction &reconstruction =
- libmv_reconstruction->reconstruction;
-
- ReconstructUpdateCallback update_callback =
- ReconstructUpdateCallback(progress_update_callback,
- callback_customdata);
-
- /* Retrieve reconstruction options from C-API to libmv API */
- CameraIntrinsics *camera_intrinsics;
- camera_intrinsics = libmv_reconstruction->intrinsics =
- libmv_cameraIntrinsicsCreateFromOptions(
- libmv_camera_intrinsics_options);
-
- /* Invert the camera intrinsics. */
- Tracks normalized_tracks;
- libmv_getNormalizedTracks(tracks, *camera_intrinsics, &normalized_tracks);
-
- /* Actual reconstruction. */
- ModalSolver(normalized_tracks, &reconstruction, &update_callback);
-
- PolynomialCameraIntrinsics empty_intrinsics;
- EuclideanBundleCommonIntrinsics(normalized_tracks,
- libmv::BUNDLE_NO_INTRINSICS,
- libmv::BUNDLE_NO_TRANSLATION,
- &reconstruction,
- &empty_intrinsics);
-
- /* Refinement. */
- if (libmv_reconstruction_options->refine_intrinsics) {
- libmv_solveRefineIntrinsics(
- tracks,
- libmv_reconstruction_options->refine_intrinsics,
- libmv::BUNDLE_NO_TRANSLATION,
- progress_update_callback, callback_customdata,
- &reconstruction,
- camera_intrinsics);
- }
-
- /* Finish reconstruction. */
- finishReconstruction(tracks,
- *camera_intrinsics,
- libmv_reconstruction,
- progress_update_callback,
- callback_customdata);
-
- return (libmv_Reconstruction *) libmv_reconstruction;
-}
-
-void libmv_reconstructionDestroy(libmv_Reconstruction *libmv_reconstruction)
-{
- LIBMV_OBJECT_DELETE(libmv_reconstruction->intrinsics, CameraIntrinsics);
- LIBMV_OBJECT_DELETE(libmv_reconstruction, libmv_Reconstruction);
-}
-
-int libmv_reprojectionPointForTrack(
- const libmv_Reconstruction *libmv_reconstruction,
- int track,
- double pos[3])
-{
- const EuclideanReconstruction *reconstruction =
- &libmv_reconstruction->reconstruction;
- const EuclideanPoint *point =
- reconstruction->PointForTrack(track);
-
- if (point) {
- pos[0] = point->X[0];
- pos[1] = point->X[2];
- pos[2] = point->X[1];
-
- return 1;
- }
-
- return 0;
-}
-
-double libmv_reprojectionErrorForTrack(
- const libmv_Reconstruction *libmv_reconstruction,
- int track)
-{
- const EuclideanReconstruction *reconstruction =
- &libmv_reconstruction->reconstruction;
- const CameraIntrinsics *intrinsics = libmv_reconstruction->intrinsics;
- libmv::vector<Marker> markers =
- libmv_reconstruction->tracks.MarkersForTrack(track);
-
- int num_reprojected = 0;
- double total_error = 0.0;
-
- for (int i = 0; i < markers.size(); ++i) {
- double weight = markers[i].weight;
- const EuclideanCamera *camera =
- reconstruction->CameraForImage(markers[i].image);
- const EuclideanPoint *point =
- reconstruction->PointForTrack(markers[i].track);
-
- if (!camera || !point || weight == 0.0) {
- continue;
- }
-
- num_reprojected++;
-
- Marker reprojected_marker =
- libmv_projectMarker(*point, *camera, *intrinsics);
- double ex = (reprojected_marker.x - markers[i].x) * weight;
- double ey = (reprojected_marker.y - markers[i].y) * weight;
-
- total_error += sqrt(ex * ex + ey * ey);
- }
-
- return total_error / num_reprojected;
-}
-
-double libmv_reprojectionErrorForImage(
- const libmv_Reconstruction *libmv_reconstruction,
- int image)
-{
- const EuclideanReconstruction *reconstruction =
- &libmv_reconstruction->reconstruction;
- const CameraIntrinsics *intrinsics = libmv_reconstruction->intrinsics;
- libmv::vector<Marker> markers =
- libmv_reconstruction->tracks.MarkersInImage(image);
- const EuclideanCamera *camera = reconstruction->CameraForImage(image);
- int num_reprojected = 0;
- double total_error = 0.0;
-
- if (!camera) {
- return 0.0;
- }
-
- for (int i = 0; i < markers.size(); ++i) {
- const EuclideanPoint *point =
- reconstruction->PointForTrack(markers[i].track);
-
- if (!point) {
- continue;
- }
-
- num_reprojected++;
-
- Marker reprojected_marker =
- libmv_projectMarker(*point, *camera, *intrinsics);
- double ex = (reprojected_marker.x - markers[i].x) * markers[i].weight;
- double ey = (reprojected_marker.y - markers[i].y) * markers[i].weight;
-
- total_error += sqrt(ex * ex + ey * ey);
- }
-
- return total_error / num_reprojected;
-}
-
-int libmv_reprojectionCameraForImage(
- const libmv_Reconstruction *libmv_reconstruction,
- int image, double mat[4][4])
-{
- const EuclideanReconstruction *reconstruction =
- &libmv_reconstruction->reconstruction;
- const EuclideanCamera *camera =
- reconstruction->CameraForImage(image);
-
- if (camera) {
- for (int j = 0; j < 3; ++j) {
- for (int k = 0; k < 3; ++k) {
- int l = k;
-
- if (k == 1) l = 2;
- else if (k == 2) l = 1;
-
- if (j == 2) mat[j][l] = -camera->R(j,k);
- else mat[j][l] = camera->R(j,k);
- }
- mat[j][3] = 0.0;
- }
-
- libmv::Vec3 optical_center = -camera->R.transpose() * camera->t;
-
- mat[3][0] = optical_center(0);
- mat[3][1] = optical_center(2);
- mat[3][2] = optical_center(1);
-
- mat[3][3] = 1.0;
-
- return 1;
- }
-
- return 0;
-}
-
-double libmv_reprojectionError(
- const libmv_Reconstruction *libmv_reconstruction)
-{
- return libmv_reconstruction->error;
-}
-
-libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(
- libmv_Reconstruction *libmv_reconstruction)
-{
- return (libmv_CameraIntrinsics *) libmv_reconstruction->intrinsics;
-}
-
-/* ************ Feature detector ************ */
-
-static libmv_Features *libmv_featuresFromVector(
- const libmv::vector<Feature> &features)
-{
- libmv_Features *libmv_features = LIBMV_STRUCT_NEW(libmv_Features, 1);
- int count = features.size();
- if (count) {
- libmv_features->features = LIBMV_STRUCT_NEW(Feature, count);
-
- for (int i = 0; i < count; i++) {
- libmv_features->features[i] = features.at(i);
- }
- }
- else {
- libmv_features->features = NULL;
- }
-
- libmv_features->count = count;
-
- return libmv_features;
-}
-
-static void libmv_convertDetectorOptions(libmv_DetectOptions *options,
- DetectOptions *detector_options)
-{
- switch (options->detector) {
-#define LIBMV_CONVERT(the_detector) \
- case LIBMV_DETECTOR_ ## the_detector: \
- detector_options->type = DetectOptions::the_detector; \
- break;
- LIBMV_CONVERT(FAST)
- LIBMV_CONVERT(MORAVEC)
- LIBMV_CONVERT(HARRIS)
-#undef LIBMV_CONVERT
- }
- detector_options->margin = options->margin;
- detector_options->min_distance = options->min_distance;
- detector_options->fast_min_trackness = options->fast_min_trackness;
- detector_options->moravec_max_count = options->moravec_max_count;
- detector_options->moravec_pattern = options->moravec_pattern;
- detector_options->harris_threshold = options->harris_threshold;
-}
-
-libmv_Features *libmv_detectFeaturesByte(
- const unsigned char *image_buffer,
- int width, int height,
- int channels,
- libmv_DetectOptions *options)
-{
- // Prepare the image.
- FloatImage image;
- libmv_byteBufferToImage(image_buffer, width, height, channels, &image);
-
- // Configure detector.
- DetectOptions detector_options;
- libmv_convertDetectorOptions(options, &detector_options);
-
- // Run the detector.
- libmv::vector<Feature> detected_features;
- Detect(image, detector_options, &detected_features);
-
- // Convert result to C-API.
- libmv_Features *result = libmv_featuresFromVector(detected_features);
- return result;
-}
-
-libmv_Features *libmv_detectFeaturesFloat(const float *image_buffer,
- int width, int height,
- int channels,
- libmv_DetectOptions *options)
-{
- // Prepare the image.
- FloatImage image;
- libmv_floatBufferToImage(image_buffer, width, height, channels, &image);
-
- // Configure detector.
- DetectOptions detector_options;
- libmv_convertDetectorOptions(options, &detector_options);
-
- // Run the detector.
- libmv::vector<Feature> detected_features;
- Detect(image, detector_options, &detected_features);
-
- // Convert result to C-API.
- libmv_Features *result = libmv_featuresFromVector(detected_features);
- return result;
-}
-
-void libmv_featuresDestroy(libmv_Features *libmv_features)
-{
- if (libmv_features->features) {
- LIBMV_STRUCT_DELETE(libmv_features->features);
- }
-
- LIBMV_STRUCT_DELETE(libmv_features);
-}
-
-int libmv_countFeatures(const libmv_Features *libmv_features)
-{
- return libmv_features->count;
-}
-
-void libmv_getFeature(const libmv_Features *libmv_features,
- int number,
- double *x, double *y, double *score, double *size)
-{
- Feature &feature = libmv_features->features[number];
-
- *x = feature.x;
- *y = feature.y;
- *score = feature.score;
- *size = feature.size;
-}
-
-/* ************ Camera intrinsics ************ */
-
-libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
- const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options)
-{
- CameraIntrinsics *camera_intrinsics =
- libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
-
- return (libmv_CameraIntrinsics *) camera_intrinsics;
-}
-
-libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(
- const libmv_CameraIntrinsics *libmvIntrinsics)
-{
- const CameraIntrinsics *orig_intrinsics =
- (const CameraIntrinsics *) libmvIntrinsics;
-
- CameraIntrinsics *new_intrinsics = NULL;
-
- switch (orig_intrinsics->GetDistortionModelType()) {
- case libmv::DISTORTION_MODEL_POLYNOMIAL:
- {
- const PolynomialCameraIntrinsics *polynomial_intrinsics =
- static_cast<const PolynomialCameraIntrinsics*>(orig_intrinsics);
- new_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics,
- *polynomial_intrinsics);
- break;
- }
- case libmv::DISTORTION_MODEL_DIVISION:
- {
- const DivisionCameraIntrinsics *division_intrinsics =
- static_cast<const DivisionCameraIntrinsics*>(orig_intrinsics);
- new_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics,
- *division_intrinsics);
- break;
- }
- default:
- assert(!"Unknown distortion model");
- }
-
- return (libmv_CameraIntrinsics *) new_intrinsics;
-}
-
-void libmv_cameraIntrinsicsDestroy(libmv_CameraIntrinsics *libmvIntrinsics)
-{
- LIBMV_OBJECT_DELETE(libmvIntrinsics, CameraIntrinsics);
-}
-
-void libmv_cameraIntrinsicsUpdate(
- const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- libmv_CameraIntrinsics *libmv_intrinsics)
-{
- CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
-
- double focal_length = libmv_camera_intrinsics_options->focal_length;
- double principal_x = libmv_camera_intrinsics_options->principal_point_x;
- double principal_y = libmv_camera_intrinsics_options->principal_point_y;
- int image_width = libmv_camera_intrinsics_options->image_width;
- int image_height = libmv_camera_intrinsics_options->image_height;
-
- /* Try avoid unnecessary updates,
- * so pre-computed distortion grids are not freed.
- */
-
- if (camera_intrinsics->focal_length() != focal_length)
- camera_intrinsics->SetFocalLength(focal_length, focal_length);
-
- if (camera_intrinsics->principal_point_x() != principal_x ||
- camera_intrinsics->principal_point_y() != principal_y)
- {
- camera_intrinsics->SetPrincipalPoint(principal_x, principal_y);
- }
-
- if (camera_intrinsics->image_width() != image_width ||
- camera_intrinsics->image_height() != image_height)
- {
- camera_intrinsics->SetImageSize(image_width, image_height);
- }
-
- switch (libmv_camera_intrinsics_options->distortion_model) {
- case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
- {
- assert(camera_intrinsics->GetDistortionModelType() ==
- libmv::DISTORTION_MODEL_POLYNOMIAL);
-
- PolynomialCameraIntrinsics *polynomial_intrinsics =
- (PolynomialCameraIntrinsics *) camera_intrinsics;
-
- double k1 = libmv_camera_intrinsics_options->polynomial_k1;
- double k2 = libmv_camera_intrinsics_options->polynomial_k2;
- double k3 = libmv_camera_intrinsics_options->polynomial_k3;
-
- if (polynomial_intrinsics->k1() != k1 ||
- polynomial_intrinsics->k2() != k2 ||
- polynomial_intrinsics->k3() != k3)
- {
- polynomial_intrinsics->SetRadialDistortion(k1, k2, k3);
- }
-
- break;
- }
-
- case LIBMV_DISTORTION_MODEL_DIVISION:
- {
- assert(camera_intrinsics->GetDistortionModelType() ==
- libmv::DISTORTION_MODEL_DIVISION);
-
- DivisionCameraIntrinsics *division_intrinsics =
- (DivisionCameraIntrinsics *) camera_intrinsics;
-
- double k1 = libmv_camera_intrinsics_options->division_k1;
- double k2 = libmv_camera_intrinsics_options->division_k2;
-
- if (division_intrinsics->k1() != k1 ||
- division_intrinsics->k2() != k2)
- {
- division_intrinsics->SetDistortion(k1, k2);
- }
-
- break;
- }
-
- default:
- assert(!"Unknown distortion model");
- }
-}
-
-void libmv_cameraIntrinsicsSetThreads(
- libmv_CameraIntrinsics *libmv_intrinsics, int threads)
-{
- CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
-
- camera_intrinsics->SetThreads(threads);
-}
-
-void libmv_cameraIntrinsicsExtractOptions(
- const libmv_CameraIntrinsics *libmv_intrinsics,
- libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
-{
- const CameraIntrinsics *camera_intrinsics =
- (const CameraIntrinsics *) libmv_intrinsics;
-
- // Fill in options which are common for all distortion models.
- camera_intrinsics_options->focal_length = camera_intrinsics->focal_length();
- camera_intrinsics_options->principal_point_x =
- camera_intrinsics->principal_point_x();
- camera_intrinsics_options->principal_point_y =
- camera_intrinsics->principal_point_y();
-
- camera_intrinsics_options->image_width = camera_intrinsics->image_width();
- camera_intrinsics_options->image_height = camera_intrinsics->image_height();
-
- switch (camera_intrinsics->GetDistortionModelType()) {
- case libmv::DISTORTION_MODEL_POLYNOMIAL:
- {
- const PolynomialCameraIntrinsics *polynomial_intrinsics =
- static_cast<const PolynomialCameraIntrinsics *>(camera_intrinsics);
- camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_POLYNOMIAL;
- camera_intrinsics_options->polynomial_k1 = polynomial_intrinsics->k1();
- camera_intrinsics_options->polynomial_k2 = polynomial_intrinsics->k2();
- camera_intrinsics_options->polynomial_k3 = polynomial_intrinsics->k3();
- camera_intrinsics_options->polynomial_p1 = polynomial_intrinsics->p1();
- camera_intrinsics_options->polynomial_p1 = polynomial_intrinsics->p2();
- break;
- }
-
- case libmv::DISTORTION_MODEL_DIVISION:
- {
- const DivisionCameraIntrinsics *division_intrinsics =
- static_cast<const DivisionCameraIntrinsics *>(camera_intrinsics);
- camera_intrinsics_options->distortion_model = LIBMV_DISTORTION_MODEL_DIVISION;
- camera_intrinsics_options->division_k1 = division_intrinsics->k1();
- camera_intrinsics_options->division_k2 = division_intrinsics->k2();
- break;
- }
-
- default:
- assert(!"Uknown distortion model");
- }
-}
-
-void libmv_cameraIntrinsicsUndistortByte(
- const libmv_CameraIntrinsics *libmv_intrinsics,
- unsigned char *src, unsigned char *dst, int width, int height,
- float overscan, int channels)
-{
- CameraIntrinsics *camera_intrinsics = (CameraIntrinsics *) libmv_intrinsics;
- camera_intrinsics->UndistortBuffer(src,
- width, height, overscan, channels,
- dst);
-}
-
-void libmv_cameraIntrinsicsUndistortFloat(
- const libmv_CameraIntrinsics *libmvIntrinsics,
- float *src, float *dst, int width, int height,
- float overscan, int channels)
-{
- CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmvIntrinsics;
- intrinsics->UndistortBuffer(src,
- width, height, overscan, channels,
- dst);
-}
-
-void libmv_cameraIntrinsicsDistortByte(
- const libmv_CameraIntrinsics *libmvIntrinsics,
- unsigned char *src, unsigned char *dst, int width, int height,
- float overscan, int channels)
-{
- CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmvIntrinsics;
- intrinsics->DistortBuffer(src,
- width, height, overscan, channels,
- dst);
-}
-
-void libmv_cameraIntrinsicsDistortFloat(
- const libmv_CameraIntrinsics *libmvIntrinsics,
- float *src, float *dst, int width, int height,
- float overscan, int channels)
-{
- CameraIntrinsics *intrinsics = (CameraIntrinsics *) libmvIntrinsics;
- intrinsics->DistortBuffer(src,
- width, height, overscan, channels,
- dst);
-}
-
-void libmv_cameraIntrinsicsApply(
- const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- double x, double y, double *x1, double *y1)
-{
- /* do a lens undistortion if focal length is non-zero only */
- if (libmv_camera_intrinsics_options->focal_length) {
- CameraIntrinsics *camera_intrinsics =
- libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
-
- camera_intrinsics->ApplyIntrinsics(x, y, x1, y1);
-
- LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
- }
-}
-
-void libmv_cameraIntrinsicsInvert(
- const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- double x, double y, double *x1, double *y1)
-{
- /* do a lens distortion if focal length is non-zero only */
- if (libmv_camera_intrinsics_options->focal_length) {
- CameraIntrinsics *camera_intrinsics =
- libmv_cameraIntrinsicsCreateFromOptions(libmv_camera_intrinsics_options);
-
- camera_intrinsics->InvertIntrinsics(x, y, x1, y1);
-
- LIBMV_OBJECT_DELETE(camera_intrinsics, CameraIntrinsics);
- }
-}
-
-void libmv_homography2DFromCorrespondencesEuc(double (*x1)[2],
- double (*x2)[2],
- int num_points,
- double H[3][3])
-{
- libmv::Mat x1_mat, x2_mat;
- libmv::Mat3 H_mat;
-
- x1_mat.resize(2, num_points);
- x2_mat.resize(2, num_points);
-
- for (int i = 0; i < num_points; i++) {
- x1_mat.col(i) = libmv::Vec2(x1[i][0], x1[i][1]);
- x2_mat.col(i) = libmv::Vec2(x2[i][0], x2[i][1]);
- }
-
- LG << "x1: " << x1_mat;
- LG << "x2: " << x2_mat;
-
- libmv::EstimateHomographyOptions options;
- libmv::EstimateHomography2DFromCorrespondences(x1_mat,
- x2_mat,
- options,
- &H_mat);
-
- LG << "H: " << H_mat;
-
- memcpy(H, H_mat.data(), 9 * sizeof(double));
-}
-
-#endif
diff --git a/extern/libmv/libmv-capi.h b/extern/libmv/libmv-capi.h
index 5cd9936723b..524f1822bc7 100644
--- a/extern/libmv/libmv-capi.h
+++ b/extern/libmv/libmv-capi.h
@@ -27,180 +27,13 @@
#ifndef LIBMV_C_API_H
#define LIBMV_C_API_H
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct libmv_Tracks;
-struct libmv_Reconstruction;
-struct libmv_Features;
-struct libmv_CameraIntrinsics;
-
-/* Logging */
-void libmv_initLogging(const char *argv0);
-void libmv_startDebugLogging(void);
-void libmv_setLoggingVerbosity(int verbosity);
-
-/* Planar tracker */
-typedef struct libmv_TrackRegionOptions {
- int motion_model;
- int num_iterations;
- int use_brute;
- int use_normalization;
- double minimum_correlation;
- double sigma;
- float *image1_mask;
-} libmv_TrackRegionOptions;
-
-typedef struct libmv_TrackRegionResult {
- int termination;
- const char *termination_reason;
- double correlation;
-} libmv_TrackRegionResult;
-
-int libmv_trackRegion(const libmv_TrackRegionOptions *options,
- const float *image1, int image1_width, int image1_height,
- const float *image2, int image2_width, int image2_height,
- const double *x1, const double *y1,
- libmv_TrackRegionResult *result,
- double *x2, double *y2);
-void libmv_samplePlanarPatch(const float *image,
- int width, int height,
- int channels,
- const double *xs, const double *ys,
- int num_samples_x, int num_samples_y,
- const float *mask,
- float *patch,
- double *warped_position_x, double *warped_position_y);
-void libmv_samplePlanarPatchByte(const unsigned char *image,
- int width, int height,
- int channels,
- const double *xs, const double *ys,
- int num_samples_x, int num_samples_y,
- const float *mask,
- unsigned char *patch,
- double *warped_position_x, double *warped_position_y);
-
-/* Tracks */
-struct libmv_Tracks *libmv_tracksNew(void);
-void libmv_tracksDestroy(struct libmv_Tracks *libmv_tracks);
-void libmv_tracksInsert(struct libmv_Tracks *libmv_tracks, int image, int track, double x, double y, double weight);
-
-/* Reconstruction */
-#define LIBMV_REFINE_FOCAL_LENGTH (1 << 0)
-#define LIBMV_REFINE_PRINCIPAL_POINT (1 << 1)
-#define LIBMV_REFINE_RADIAL_DISTORTION_K1 (1 << 2)
-#define LIBMV_REFINE_RADIAL_DISTORTION_K2 (1 << 4)
-
-enum {
- LIBMV_DISTORTION_MODEL_POLYNOMIAL = 0,
- LIBMV_DISTORTION_MODEL_DIVISION = 1,
-};
-
-typedef struct libmv_CameraIntrinsicsOptions {
- /* Common settings of all distortion models. */
- int distortion_model;
- int image_width, image_height;
- double focal_length;
- double principal_point_x, principal_point_y;
-
- /* Radial distortion model. */
- double polynomial_k1, polynomial_k2, polynomial_k3;
- double polynomial_p1, polynomial_p2;
-
- /* Division distortion model. */
- double division_k1, division_k2;
-} libmv_CameraIntrinsicsOptions;
-
-typedef struct libmv_ReconstructionOptions {
- int select_keyframes;
- int keyframe1, keyframe2;
-
- int refine_intrinsics;
-} libmv_ReconstructionOptions;
-
-typedef void (*reconstruct_progress_update_cb) (void *customdata, double progress, const char *message);
-
-struct libmv_Reconstruction *libmv_solveReconstruction(const struct libmv_Tracks *libmv_tracks,
- const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- libmv_ReconstructionOptions *libmv_reconstruction_options,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata);
-struct libmv_Reconstruction *libmv_solveModal(const struct libmv_Tracks *libmv_tracks,
- const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- const libmv_ReconstructionOptions *libmv_reconstruction_options,
- reconstruct_progress_update_cb progress_update_callback,
- void *callback_customdata);
-void libmv_reconstructionDestroy(struct libmv_Reconstruction *libmv_reconstruction);
-int libmv_reprojectionPointForTrack(const struct libmv_Reconstruction *libmv_reconstruction, int track, double pos[3]);
-double libmv_reprojectionErrorForTrack(const struct libmv_Reconstruction *libmv_reconstruction, int track);
-double libmv_reprojectionErrorForImage(const struct libmv_Reconstruction *libmv_reconstruction, int image);
-int libmv_reprojectionCameraForImage(const struct libmv_Reconstruction *libmv_reconstruction,
- int image, double mat[4][4]);
-double libmv_reprojectionError(const struct libmv_Reconstruction *libmv_reconstruction);
-struct libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(struct libmv_Reconstruction *libmv_Reconstruction);
-
-/* Feature detector */
-enum {
- LIBMV_DETECTOR_FAST,
- LIBMV_DETECTOR_MORAVEC,
- LIBMV_DETECTOR_HARRIS,
-};
-
-typedef struct libmv_DetectOptions {
- int detector;
- int margin;
- int min_distance;
- int fast_min_trackness;
- int moravec_max_count;
- unsigned char *moravec_pattern;
- double harris_threshold;
-} libmv_DetectOptions;
-
-struct libmv_Features *libmv_detectFeaturesByte(const unsigned char *image_buffer,
- int width, int height, int channels,
- libmv_DetectOptions *options);
-struct libmv_Features *libmv_detectFeaturesFloat(const float *image_buffer,
- int width, int height, int channels,
- libmv_DetectOptions *options);
-
-void libmv_featuresDestroy(struct libmv_Features *libmv_features);
-int libmv_countFeatures(const struct libmv_Features *libmv_features);
-void libmv_getFeature(const struct libmv_Features *libmv_features, int number, double *x, double *y, double *score,
- double *size);
-
-/* Camera intrinsics */
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
- const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options);
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(const struct libmv_CameraIntrinsics *libmv_intrinsics);
-void libmv_cameraIntrinsicsDestroy(struct libmv_CameraIntrinsics *libmv_intrinsics);
-void libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- struct libmv_CameraIntrinsics *libmv_intrinsics);
-void libmv_cameraIntrinsicsSetThreads(struct libmv_CameraIntrinsics *libmv_intrinsics, int threads);
-void libmv_cameraIntrinsicsExtractOptions(
- const struct libmv_CameraIntrinsics *libmv_intrinsics,
- struct libmv_CameraIntrinsicsOptions *camera_intrinsics_options);
-void libmv_cameraIntrinsicsUndistortByte(const struct libmv_CameraIntrinsics *libmv_intrinsics,
- unsigned char *src, unsigned char *dst, int width, int height,
- float overscan, int channels);
-void libmv_cameraIntrinsicsUndistortFloat(const struct libmv_CameraIntrinsics *libmv_intrinsics,
- float *src, float *dst, int width, int height,
- float overscan, int channels);
-void libmv_cameraIntrinsicsDistortByte(const struct libmv_CameraIntrinsics *libmv_intrinsics,
- unsigned char *src, unsigned char *dst, int width, int height,
- float overscan, int channels);
-void libmv_cameraIntrinsicsDistortFloat(const struct libmv_CameraIntrinsics *libmv_intrinsics,
- float *src, float *dst, int width, int height,
- float overscan, int channels);
-void libmv_cameraIntrinsicsApply(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- double x, double y, double *x1, double *y1);
-void libmv_cameraIntrinsicsInvert(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- double x, double y, double *x1, double *y1);
-
-void libmv_homography2DFromCorrespondencesEuc(double (*x1)[2], double (*x2)[2], int num_points, double H[3][3]);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // LIBMV_C_API_H
+#include "intern/camera_intrinsics.h"
+#include "intern/detector.h"
+#include "intern/homography.h"
+#include "intern/image.h"
+#include "intern/logging.h"
+#include "intern/reconstruction.h"
+#include "intern/track_region.h"
+#include "intern/tracks.h"
+
+#endif // LIBMV_C_API_H
diff --git a/extern/libmv/libmv-capi_stub.cc b/extern/libmv/libmv-capi_stub.cc
deleted file mode 100644
index 36a3bc7ddee..00000000000
--- a/extern/libmv/libmv-capi_stub.cc
+++ /dev/null
@@ -1,293 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2013 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation,
- * Sergey Sharybin
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef WITH_LIBMV
-
-#include "libmv-capi.h"
-
-#include <cstdlib>
-#include <cstring>
-
-/* ************ Logging ************ */
-
-void libmv_initLogging(const char * /*argv0*/)
-{
-}
-
-void libmv_startDebugLogging(void)
-{
-}
-
-void libmv_setLoggingVerbosity(int /*verbosity*/)
-{
-}
-
-/* ************ Planar tracker ************ */
-
-/* TrackRegion (new planar tracker) */
-int libmv_trackRegion(const libmv_TrackRegionOptions * /*options*/,
- const float * /*image1*/, int /*image1_width*/, int /*image1_height*/,
- const float * /*image2*/, int /*image2_width*/, int /*image2_height*/,
- const double *x1, const double *y1,
- libmv_TrackRegionResult *result,
- double *x2, double *y2)
-{
- /* Convert to doubles for the libmv api. The four corners and the center. */
- for (int i = 0; i < 5; ++i) {
- x2[i] = x1[i];
- y2[i] = y1[i];
- }
-
- result->termination = -1;
- result->termination_reason = "Built without libmv support";
- result->correlation = 0.0;
-
- return false;
-}
-
-void libmv_samplePlanarPatch(const float * /*image*/,
- int /*width*/, int /*height*/, int /*channels*/,
- const double * /*xs*/, const double * /*ys*/,
- int /*num_samples_x*/, int /*num_samples_y*/,
- const float * /*mask*/,
- float * /*patch*/,
- double * /*warped_position_x*/, double * /*warped_position_y*/)
-{
- /* TODO(sergey): implement */
-}
-
-void libmv_samplePlanarPatchByte(const unsigned char * /*image*/,
- int /*width*/, int /*height*/, int /*channels*/,
- const double * /*xs*/, const double * /*ys*/,
- int /*num_samples_x*/, int /*num_samples_y*/,
- const float * /*mask*/,
- unsigned char * /*patch*/,
- double * /*warped_position_x*/, double * /*warped_position_y*/)
-{
- /* TODO(sergey): implement */
-}
-
-/* ************ Tracks ************ */
-
-struct libmv_Tracks *libmv_tracksNew(void)
-{
- return NULL;
-}
-
-void libmv_tracksInsert(struct libmv_Tracks * /*libmv_tracks*/, int /*image*/,
- int /*track*/, double /*x*/, double /*y*/, double /*weight*/)
-{
-}
-
-void libmv_tracksDestroy(struct libmv_Tracks * /*libmv_tracks*/)
-{
-}
-
-/* ************ Reconstruction solver ************ */
-
-struct libmv_Reconstruction *libmv_solveReconstruction(const struct libmv_Tracks * /*libmv_tracks*/,
- const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/,
- libmv_ReconstructionOptions * /*libmv_reconstruction_options*/,
- reconstruct_progress_update_cb /*progress_update_callback*/,
- void * /*callback_customdata*/)
-{
- return NULL;
-}
-
-struct libmv_Reconstruction *libmv_solveModal(const struct libmv_Tracks * /*libmv_tracks*/,
- const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/,
- const libmv_ReconstructionOptions * /*libmv_reconstruction_options*/,
- reconstruct_progress_update_cb /*progress_update_callback*/,
- void * /*callback_customdata*/)
-{
- return NULL;
-}
-
-int libmv_reprojectionPointForTrack(const struct libmv_Reconstruction * /*libmv_reconstruction*/,
- int /*track*/, double /*pos*/[3])
-{
- return 0;
-}
-
-double libmv_reprojectionErrorForTrack(const struct libmv_Reconstruction * /*libmv_reconstruction*/, int /*track*/)
-{
- return 0.0;
-}
-
-double libmv_reprojectionErrorForImage(const struct libmv_Reconstruction * /*libmv_reconstruction*/, int /*image*/)
-{
- return 0.0;
-}
-
-int libmv_reprojectionCameraForImage(const struct libmv_Reconstruction * /*libmv_reconstruction*/, int /*image*/,
- double /*mat*/[4][4])
-{
- return 0;
-}
-
-double libmv_reprojectionError(const struct libmv_Reconstruction * /*libmv_reconstruction*/)
-{
- return 0.0;
-}
-
-void libmv_reconstructionDestroy(struct libmv_Reconstruction * /*libmv_reconstruction*/)
-{
-}
-
-/* ************ feature detector ************ */
-
-struct libmv_Features *libmv_detectFeaturesByte(const unsigned char */*image_buffer*/,
- int /*width*/, int /*height*/, int /*channels*/,
- libmv_DetectOptions */*options*/)
-{
- return NULL;
-}
-
-struct libmv_Features *libmv_detectFeaturesFloat(const float */*image_buffer*/,
- int /*width*/, int /*height*/, int /*channels*/,
- libmv_DetectOptions */*options*/)
-{
- return NULL;
-}
-
-int libmv_countFeatures(const struct libmv_Features * /*libmv_features*/)
-{
- return 0;
-}
-
-void libmv_getFeature(const struct libmv_Features * /*libmv_features*/, int /*number*/,
- double *x, double *y, double *score, double *size)
-{
- *x = 0.0;
- *y = 0.0;
- *score = 0.0;
- *size = 0.0;
-}
-
-void libmv_featuresDestroy(struct libmv_Features * /*libmv_features*/)
-{
-}
-
-/* ************ camera intrinsics ************ */
-
-struct libmv_CameraIntrinsics *libmv_reconstructionExtractIntrinsics(
- struct libmv_Reconstruction * /*libmv_reconstruction*/)
-{
- return NULL;
-}
-
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsNew(
- const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/)
-{
- return NULL;
-}
-
-struct libmv_CameraIntrinsics *libmv_cameraIntrinsicsCopy(const libmv_CameraIntrinsics * /*libmvIntrinsics*/)
-{
- return NULL;
-}
-
-void libmv_cameraIntrinsicsDestroy(struct libmv_CameraIntrinsics * /*libmvIntrinsics*/)
-{
-}
-
-void libmv_cameraIntrinsicsUpdate(const libmv_CameraIntrinsicsOptions * /*libmv_camera_intrinsics_options*/,
- struct libmv_CameraIntrinsics * /*libmv_intrinsics*/)
-{
-}
-
-void libmv_cameraIntrinsicsSetThreads(struct libmv_CameraIntrinsics * /*libmv_intrinsics*/, int /*threads*/)
-{
-}
-
-void libmv_cameraIntrinsicsExtractOptions(
- const libmv_CameraIntrinsics */*libmv_intrinsics*/,
- libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
-{
- memset(camera_intrinsics_options, 0, sizeof(libmv_CameraIntrinsicsOptions));
- camera_intrinsics_options->focal_length = 1.0;
-}
-
-void libmv_cameraIntrinsicsUndistortByte(const struct libmv_CameraIntrinsics * /*libmv_intrinsics*/,
- unsigned char *src, unsigned char *dst, int width, int height,
- float overscan, int channels)
-{
- memcpy(dst, src, channels * width * height * sizeof(unsigned char));
-}
-
-void libmv_cameraIntrinsicsUndistortFloat(const struct libmv_CameraIntrinsics * /*libmvIntrinsics*/,
- float *src, float *dst, int width, int height, float overscan, int channels)
-{
- memcpy(dst, src, channels * width * height * sizeof(float));
-}
-
-void libmv_cameraIntrinsicsDistortByte(const struct libmv_CameraIntrinsics *libmvIntrinsics,
- unsigned char *src, unsigned char *dst, int width, int height,
- float overscan, int channels)
-{
- memcpy(dst, src, channels * width * height * sizeof(unsigned char));
-}
-
-void libmv_cameraIntrinsicsDistortFloat(const struct libmv_CameraIntrinsics *libmvIntrinsics,
- float *src, float *dst, int width, int height, float overscan, int channels)
-{
- memcpy(dst, src, channels * width * height * sizeof(float));
-}
-
-/* ************ utils ************ */
-
-void libmv_cameraIntrinsicsApply(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- double x, double y, double *x1, double *y1)
-{
- double focal_length = libmv_camera_intrinsics_options->focal_length;
- double principal_x = libmv_camera_intrinsics_options->principal_point_x;
- double principal_y = libmv_camera_intrinsics_options->principal_point_y;
-
- *x1 = x * focal_length + principal_x;
- *y1 = y * focal_length + principal_y;
-}
-
-void libmv_cameraIntrinsicsInvert(const libmv_CameraIntrinsicsOptions *libmv_camera_intrinsics_options,
- double x, double y, double *x1, double *y1)
-{
- double focal_length = libmv_camera_intrinsics_options->focal_length;
- double principal_x = libmv_camera_intrinsics_options->principal_point_x;
- double principal_y = libmv_camera_intrinsics_options->principal_point_y;
-
- *x1 = (x - principal_x) / focal_length;
- *y1 = (y - principal_y) / focal_length;
-}
-
-void libmv_homography2DFromCorrespondencesEuc(double (* /* x1 */)[2], double (* /* x2 */)[2], int /* num_points */,
- double H[3][3])
-{
- memset(H, 0, sizeof(double[3][3]));
- H[0][0] = 1.0f;
- H[1][1] = 1.0f;
- H[2][2] = 1.0f;
-}
-
-#endif // ifndef WITH_LIBMV
diff --git a/extern/libmv/libmv-util.cc b/extern/libmv/libmv-util.cc
deleted file mode 100644
index f969417d6c1..00000000000
--- a/extern/libmv/libmv-util.cc
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2014 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation,
- * Sergey Sharybin
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "libmv-util.h"
-#include "libmv-capi_intern.h"
-
-#include <cassert>
-#include <png.h>
-
-using libmv::CameraIntrinsics;
-using libmv::DivisionCameraIntrinsics;
-using libmv::EuclideanCamera;
-using libmv::EuclideanPoint;
-using libmv::FloatImage;
-using libmv::Marker;
-using libmv::PolynomialCameraIntrinsics;
-using libmv::Tracks;
-
-/* Image <-> buffers conversion */
-
-void libmv_byteBufferToImage(const unsigned char *buf,
- int width, int height, int channels,
- FloatImage *image)
-{
- int x, y, k, a = 0;
-
- image->Resize(height, width, channels);
-
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- for (k = 0; k < channels; k++) {
- (*image)(y, x, k) = (float)buf[a++] / 255.0f;
- }
- }
- }
-}
-
-void libmv_floatBufferToImage(const float *buf,
- int width, int height, int channels,
- FloatImage *image)
-{
- image->Resize(height, width, channels);
-
- for (int y = 0, a = 0; y < height; y++) {
- for (int x = 0; x < width; x++) {
- for (int k = 0; k < channels; k++) {
- (*image)(y, x, k) = buf[a++];
- }
- }
- }
-}
-
-void libmv_imageToFloatBuffer(const FloatImage &image,
- float *buf)
-{
- for (int y = 0, a = 0; y < image.Height(); y++) {
- for (int x = 0; x < image.Width(); x++) {
- for (int k = 0; k < image.Depth(); k++) {
- buf[a++] = image(y, x, k);
- }
- }
- }
-}
-
-void libmv_imageToByteBuffer(const libmv::FloatImage &image,
- unsigned char *buf)
-{
- for (int y = 0, a= 0; y < image.Height(); y++) {
- for (int x = 0; x < image.Width(); x++) {
- for (int k = 0; k < image.Depth(); k++) {
- buf[a++] = image(y, x, k) * 255.0f;
- }
- }
- }
-}
-
-/* Debugging */
-
-static void savePNGImage(png_bytep *row_pointers,
- int width, int height, int depth, int color_type,
- const char *file_name)
-{
- png_infop info_ptr;
- png_structp png_ptr;
- FILE *fp = fopen(file_name, "wb");
-
- if (!fp) {
- return;
- }
-
- /* Initialize stuff */
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- info_ptr = png_create_info_struct(png_ptr);
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- fclose(fp);
- return;
- }
-
- png_init_io(png_ptr, fp);
-
- /* write header */
- if (setjmp(png_jmpbuf(png_ptr))) {
- fclose(fp);
- return;
- }
-
- png_set_IHDR(png_ptr, info_ptr,
- width, height, depth, color_type,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_BASE,
- PNG_FILTER_TYPE_BASE);
-
- png_write_info(png_ptr, info_ptr);
-
- /* write bytes */
- if (setjmp(png_jmpbuf(png_ptr))) {
- fclose(fp);
- return;
- }
-
- png_write_image(png_ptr, row_pointers);
-
- /* end write */
- if (setjmp(png_jmpbuf(png_ptr))) {
- fclose(fp);
- return;
- }
-
- png_write_end(png_ptr, NULL);
-
- fclose(fp);
-}
-
-void libmv_saveImage(const FloatImage &image,
- const char *prefix,
- int x0, int y0)
-{
- int x, y;
- png_bytep *row_pointers;
-
- assert(image.Depth() == 1);
-
- row_pointers = new png_bytep[image.Height()];
-
- for (y = 0; y < image.Height(); y++) {
- row_pointers[y] = new png_byte[4 * image.Width()];
-
- for (x = 0; x < image.Width(); x++) {
- if (x0 == x && image.Height() - y0 - 1 == y) {
- row_pointers[y][x * 4 + 0] = 255;
- row_pointers[y][x * 4 + 1] = 0;
- row_pointers[y][x * 4 + 2] = 0;
- row_pointers[y][x * 4 + 3] = 255;
- }
- else {
- float pixel = image(image.Height() - y - 1, x, 0);
- row_pointers[y][x * 4 + 0] = pixel * 255;
- row_pointers[y][x * 4 + 1] = pixel * 255;
- row_pointers[y][x * 4 + 2] = pixel * 255;
- row_pointers[y][x * 4 + 3] = 255;
- }
- }
- }
-
- {
- static int a = 0;
- char buf[128];
- snprintf(buf, sizeof(buf), "%s_%02d.png", prefix, ++a);
- savePNGImage(row_pointers,
- image.Width(), image.Height(), 8,
- PNG_COLOR_TYPE_RGBA,
- buf);
- }
-
- for (y = 0; y < image.Height(); y++) {
- delete [] row_pointers[y];
- }
- delete [] row_pointers;
-}
-
-/* Camera intrinsics utility functions */
-
-void libmv_cameraIntrinsicsFillFromOptions(
- const libmv_CameraIntrinsicsOptions *camera_intrinsics_options,
- CameraIntrinsics *camera_intrinsics)
-{
- camera_intrinsics->SetFocalLength(camera_intrinsics_options->focal_length,
- camera_intrinsics_options->focal_length);
-
- camera_intrinsics->SetPrincipalPoint(
- camera_intrinsics_options->principal_point_x,
- camera_intrinsics_options->principal_point_y);
-
- camera_intrinsics->SetImageSize(camera_intrinsics_options->image_width,
- camera_intrinsics_options->image_height);
-
- switch (camera_intrinsics_options->distortion_model) {
- case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
- {
- PolynomialCameraIntrinsics *polynomial_intrinsics =
- static_cast<PolynomialCameraIntrinsics*>(camera_intrinsics);
-
- polynomial_intrinsics->SetRadialDistortion(
- camera_intrinsics_options->polynomial_k1,
- camera_intrinsics_options->polynomial_k2,
- camera_intrinsics_options->polynomial_k3);
-
- break;
- }
-
- case LIBMV_DISTORTION_MODEL_DIVISION:
- {
- DivisionCameraIntrinsics *division_intrinsics =
- static_cast<DivisionCameraIntrinsics*>(camera_intrinsics);
-
- division_intrinsics->SetDistortion(
- camera_intrinsics_options->division_k1,
- camera_intrinsics_options->division_k2);
-
- break;
- }
-
- default:
- assert(!"Unknown distortion model");
- }
-}
-
-CameraIntrinsics *libmv_cameraIntrinsicsCreateFromOptions(
- const libmv_CameraIntrinsicsOptions *camera_intrinsics_options)
-{
- CameraIntrinsics *camera_intrinsics = NULL;
-
- switch (camera_intrinsics_options->distortion_model) {
- case LIBMV_DISTORTION_MODEL_POLYNOMIAL:
- camera_intrinsics = LIBMV_OBJECT_NEW(PolynomialCameraIntrinsics);
- break;
-
- case LIBMV_DISTORTION_MODEL_DIVISION:
- camera_intrinsics = LIBMV_OBJECT_NEW(DivisionCameraIntrinsics);
- break;
-
- default:
- assert(!"Unknown distortion model");
- }
-
- libmv_cameraIntrinsicsFillFromOptions(camera_intrinsics_options, camera_intrinsics);
-
- return camera_intrinsics;
-}
-
-/* Reconstruction utilities */
-
-void libmv_getNormalizedTracks(const Tracks &tracks,
- const CameraIntrinsics &camera_intrinsics,
- Tracks *normalized_tracks)
-{
- libmv::vector<Marker> markers = tracks.AllMarkers();
-
- for (int i = 0; i < markers.size(); ++i) {
- Marker &marker = markers[i];
- camera_intrinsics.InvertIntrinsics(marker.x, marker.y,
- &marker.x, &marker.y);
- normalized_tracks->Insert(marker.image, marker.track,
- marker.x, marker.y,
- marker.weight);
- }
-}
-
-Marker libmv_projectMarker(const EuclideanPoint &point,
- const EuclideanCamera &camera,
- const CameraIntrinsics &intrinsics)
-{
- libmv::Vec3 projected = camera.R * point.X + camera.t;
- projected /= projected(2);
-
- libmv::Marker reprojected_marker;
- intrinsics.ApplyIntrinsics(projected(0), projected(1),
- &reprojected_marker.x,
- &reprojected_marker.y);
-
- reprojected_marker.image = camera.image;
- reprojected_marker.track = point.track;
-
- return reprojected_marker;
-}
diff --git a/extern/libmv/libmv-util.h b/extern/libmv/libmv-util.h
deleted file mode 100644
index d755f98d06d..00000000000
--- a/extern/libmv/libmv-util.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2014 Blender Foundation.
- * All rights reserved.
- *
- * Contributor(s): Blender Foundation,
- * Sergey Sharybin
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef LIBMV_UTIL_H
-#define LIBMV_UTIL_H
-
-#include "libmv-capi.h"
-#include "libmv/image/image.h"
-#include "libmv/simple_pipeline/camera_intrinsics.h"
-#include "libmv/simple_pipeline/tracks.h"
-#include "libmv/simple_pipeline/reconstruction.h"
-
-void libmv_byteBufferToImage(const unsigned char *buf,
- int width, int height, int channels,
- libmv::FloatImage *image);
-
-void libmv_floatBufferToImage(const float *buf,
- int width, int height, int channels,
- libmv::FloatImage *image);
-
-void libmv_imageToFloatBuffer(const libmv::FloatImage &image,
- float *buf);
-
-void libmv_imageToByteBuffer(const libmv::FloatImage &image,
- unsigned char *buf);
-
-void libmv_saveImage(const libmv::FloatImage &image,
- const char *prefix,
- int x0, int y0);
-
-void libmv_cameraIntrinsicsFillFromOptions(
- const libmv_CameraIntrinsicsOptions *camera_intrinsics_options,
- libmv::CameraIntrinsics *camera_intrinsics);
-
-libmv::CameraIntrinsics *libmv_cameraIntrinsicsCreateFromOptions(
- const libmv_CameraIntrinsicsOptions *camera_intrinsics_options);
-
-void libmv_getNormalizedTracks(const libmv::Tracks &tracks,
- const libmv::CameraIntrinsics &camera_intrinsics,
- libmv::Tracks *normalized_tracks);
-
-libmv::Marker libmv_projectMarker(const libmv::EuclideanPoint &point,
- const libmv::EuclideanCamera &camera,
- const libmv::CameraIntrinsics &intrinsics);
-
-#endif
diff --git a/extern/libmv/libmv/simple_pipeline/bundle.cc b/extern/libmv/libmv/simple_pipeline/bundle.cc
index 09b55f34eef..e61650fb371 100644
--- a/extern/libmv/libmv/simple_pipeline/bundle.cc
+++ b/extern/libmv/libmv/simple_pipeline/bundle.cc
@@ -424,6 +424,7 @@ void EuclideanBundlePointsOnly(const DistortionModelType distortion_model,
options.use_nonmonotonic_steps = true;
options.preconditioner_type = ceres::SCHUR_JACOBI;
options.linear_solver_type = ceres::ITERATIVE_SCHUR;
+ options.use_explicit_schur_complement = true;
options.use_inner_iterations = true;
options.max_num_iterations = 100;
@@ -593,6 +594,7 @@ void EuclideanBundleCommonIntrinsics(
options.use_nonmonotonic_steps = true;
options.preconditioner_type = ceres::SCHUR_JACOBI;
options.linear_solver_type = ceres::ITERATIVE_SCHUR;
+ options.use_explicit_schur_complement = true;
options.use_inner_iterations = true;
options.max_num_iterations = 100;
diff --git a/extern/libmv/third_party/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/CMakeLists.txt
index 770803868cc..0ca888f6393 100644
--- a/extern/libmv/third_party/ceres/CMakeLists.txt
+++ b/extern/libmv/third_party/ceres/CMakeLists.txt
@@ -51,6 +51,7 @@ set(SRC
internal/ceres/block_random_access_sparse_matrix.cc
internal/ceres/block_sparse_matrix.cc
internal/ceres/block_structure.cc
+ internal/ceres/callbacks.cc
internal/ceres/canonical_views_clustering.cc
internal/ceres/c_api.cc
internal/ceres/cgnr_solver.cc
@@ -76,6 +77,8 @@ set(SRC
internal/ceres/generated/partitioned_matrix_view_d_d_d.cc
internal/ceres/generated/schur_eliminator_d_d_d.cc
internal/ceres/gradient_checking_cost_function.cc
+ internal/ceres/gradient_problem.cc
+ internal/ceres/gradient_problem_solver.cc
internal/ceres/implicit_schur_complement.cc
internal/ceres/incomplete_lq_factorization.cc
internal/ceres/iterative_schur_complement_solver.cc
@@ -87,6 +90,7 @@ set(SRC
internal/ceres/line_search.cc
internal/ceres/line_search_direction.cc
internal/ceres/line_search_minimizer.cc
+ internal/ceres/line_search_preprocessor.cc
internal/ceres/local_parameterization.cc
internal/ceres/loss_function.cc
internal/ceres/low_rank_inverse_hessian.cc
@@ -96,9 +100,11 @@ set(SRC
internal/ceres/partitioned_matrix_view.cc
internal/ceres/polynomial.cc
internal/ceres/preconditioner.cc
+ internal/ceres/preprocessor.cc
internal/ceres/problem.cc
internal/ceres/problem_impl.cc
internal/ceres/program.cc
+ internal/ceres/reorder_program.cc
internal/ceres/residual_block.cc
internal/ceres/residual_block_utils.cc
internal/ceres/schur_complement_solver.cc
@@ -107,7 +113,7 @@ set(SRC
internal/ceres/scratch_evaluate_preparer.cc
internal/ceres/single_linkage_clustering.cc
internal/ceres/solver.cc
- internal/ceres/solver_impl.cc
+ internal/ceres/solver_utils.cc
internal/ceres/sparse_matrix.cc
internal/ceres/sparse_normal_cholesky_solver.cc
internal/ceres/split.cc
@@ -115,6 +121,7 @@ set(SRC
internal/ceres/suitesparse.cc
internal/ceres/triplet_sparse_matrix.cc
internal/ceres/trust_region_minimizer.cc
+ internal/ceres/trust_region_preprocessor.cc
internal/ceres/trust_region_strategy.cc
internal/ceres/types.cc
internal/ceres/visibility_based_preconditioner.cc
@@ -134,13 +141,17 @@ set(SRC
include/ceres/dynamic_numeric_diff_cost_function.h
include/ceres/fpclassify.h
include/ceres/gradient_checker.h
+ include/ceres/gradient_problem.h
+ include/ceres/gradient_problem_solver.h
include/ceres/internal/autodiff.h
+ include/ceres/internal/disable_warnings.h
include/ceres/internal/eigen.h
include/ceres/internal/fixed_array.h
include/ceres/internal/macros.h
include/ceres/internal/manual_constructor.h
include/ceres/internal/numeric_diff.h
include/ceres/internal/port.h
+ include/ceres/internal/reenable_warnings.h
include/ceres/internal/scoped_ptr.h
include/ceres/internal/variadic_evaluate.h
include/ceres/iteration_callback.h
@@ -149,13 +160,13 @@ set(SRC
include/ceres/loss_function.h
include/ceres/normal_prior.h
include/ceres/numeric_diff_cost_function.h
- include/ceres/numeric_diff_functor.h
include/ceres/ordered_groups.h
include/ceres/problem.h
include/ceres/rotation.h
include/ceres/sized_cost_function.h
include/ceres/solver.h
include/ceres/types.h
+ include/ceres/version.h
internal/ceres/array_utils.h
internal/ceres/blas.h
internal/ceres/block_evaluate_preparer.h
@@ -167,6 +178,7 @@ set(SRC
internal/ceres/block_random_access_sparse_matrix.h
internal/ceres/block_sparse_matrix.h
internal/ceres/block_structure.h
+ internal/ceres/callbacks.h
internal/ceres/canonical_views_clustering.h
internal/ceres/casts.h
internal/ceres/cgnr_linear_operator.h
@@ -193,6 +205,7 @@ set(SRC
internal/ceres/execution_summary.h
internal/ceres/file.h
internal/ceres/gradient_checking_cost_function.h
+ internal/ceres/gradient_problem_evaluator.h
internal/ceres/graph_algorithms.h
internal/ceres/graph.h
internal/ceres/implicit_schur_complement.h
@@ -207,6 +220,7 @@ set(SRC
internal/ceres/line_search_direction.h
internal/ceres/line_search.h
internal/ceres/line_search_minimizer.h
+ internal/ceres/line_search_preprocessor.h
internal/ceres/low_rank_inverse_hessian.h
internal/ceres/map_util.h
internal/ceres/minimizer.h
@@ -217,10 +231,12 @@ set(SRC
internal/ceres/partitioned_matrix_view_impl.h
internal/ceres/polynomial.h
internal/ceres/preconditioner.h
+ internal/ceres/preprocessor.h
internal/ceres/problem_impl.h
internal/ceres/program_evaluator.h
internal/ceres/program.h
internal/ceres/random.h
+ internal/ceres/reorder_program.h
internal/ceres/residual_block.h
internal/ceres/residual_block_utils.h
internal/ceres/schur_complement_solver.h
@@ -230,7 +246,7 @@ set(SRC
internal/ceres/scratch_evaluate_preparer.h
internal/ceres/single_linkage_clustering.h
internal/ceres/small_blas.h
- internal/ceres/solver_impl.h
+ internal/ceres/solver_utils.h
internal/ceres/sparse_matrix.h
internal/ceres/sparse_normal_cholesky_solver.h
internal/ceres/split.h
@@ -239,52 +255,55 @@ set(SRC
internal/ceres/suitesparse.h
internal/ceres/triplet_sparse_matrix.h
internal/ceres/trust_region_minimizer.h
+ internal/ceres/trust_region_preprocessor.h
internal/ceres/trust_region_strategy.h
internal/ceres/visibility_based_preconditioner.h
internal/ceres/visibility.h
internal/ceres/wall_time.h
)
-#if(FALSE)
-# list(APPEND SRC
-# internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
-# internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
-# internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
-# internal/ceres/generated/partitioned_matrix_view_2_2_d.cc
-# internal/ceres/generated/partitioned_matrix_view_2_3_3.cc
-# internal/ceres/generated/partitioned_matrix_view_2_3_4.cc
-# internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
-# internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
-# internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
-# internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
-# internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
-# internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
-# internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
-# internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
-# internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
-# internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
-# internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
-# internal/ceres/generated/partitioned_matrix_view_4_4_d.cc
-# internal/ceres/generated/schur_eliminator_2_2_2.cc
-# internal/ceres/generated/schur_eliminator_2_2_3.cc
-# internal/ceres/generated/schur_eliminator_2_2_4.cc
-# internal/ceres/generated/schur_eliminator_2_2_d.cc
-# internal/ceres/generated/schur_eliminator_2_3_3.cc
-# internal/ceres/generated/schur_eliminator_2_3_4.cc
-# internal/ceres/generated/schur_eliminator_2_3_9.cc
-# internal/ceres/generated/schur_eliminator_2_3_d.cc
-# internal/ceres/generated/schur_eliminator_2_4_3.cc
-# internal/ceres/generated/schur_eliminator_2_4_4.cc
-# internal/ceres/generated/schur_eliminator_2_4_8.cc
-# internal/ceres/generated/schur_eliminator_2_4_9.cc
-# internal/ceres/generated/schur_eliminator_2_4_d.cc
-# internal/ceres/generated/schur_eliminator_2_d_d.cc
-# internal/ceres/generated/schur_eliminator_4_4_2.cc
-# internal/ceres/generated/schur_eliminator_4_4_3.cc
-# internal/ceres/generated/schur_eliminator_4_4_4.cc
-# internal/ceres/generated/schur_eliminator_4_4_d.cc
-# )
-#endif()
+if(WITH_LIBMV_SCHUR_SPECIALIZATIONS)
+ list(APPEND SRC
+ internal/ceres/generated/partitioned_matrix_view_2_2_2.cc
+ internal/ceres/generated/partitioned_matrix_view_2_2_3.cc
+ internal/ceres/generated/partitioned_matrix_view_2_2_4.cc
+ internal/ceres/generated/partitioned_matrix_view_2_2_d.cc
+ internal/ceres/generated/partitioned_matrix_view_2_3_3.cc
+ internal/ceres/generated/partitioned_matrix_view_2_3_4.cc
+ internal/ceres/generated/partitioned_matrix_view_2_3_9.cc
+ internal/ceres/generated/partitioned_matrix_view_2_3_d.cc
+ internal/ceres/generated/partitioned_matrix_view_2_4_3.cc
+ internal/ceres/generated/partitioned_matrix_view_2_4_4.cc
+ internal/ceres/generated/partitioned_matrix_view_2_4_8.cc
+ internal/ceres/generated/partitioned_matrix_view_2_4_9.cc
+ internal/ceres/generated/partitioned_matrix_view_2_4_d.cc
+ internal/ceres/generated/partitioned_matrix_view_2_d_d.cc
+ internal/ceres/generated/partitioned_matrix_view_4_4_2.cc
+ internal/ceres/generated/partitioned_matrix_view_4_4_3.cc
+ internal/ceres/generated/partitioned_matrix_view_4_4_4.cc
+ internal/ceres/generated/partitioned_matrix_view_4_4_d.cc
+ internal/ceres/generated/schur_eliminator_2_2_2.cc
+ internal/ceres/generated/schur_eliminator_2_2_3.cc
+ internal/ceres/generated/schur_eliminator_2_2_4.cc
+ internal/ceres/generated/schur_eliminator_2_2_d.cc
+ internal/ceres/generated/schur_eliminator_2_3_3.cc
+ internal/ceres/generated/schur_eliminator_2_3_4.cc
+ internal/ceres/generated/schur_eliminator_2_3_9.cc
+ internal/ceres/generated/schur_eliminator_2_3_d.cc
+ internal/ceres/generated/schur_eliminator_2_4_3.cc
+ internal/ceres/generated/schur_eliminator_2_4_4.cc
+ internal/ceres/generated/schur_eliminator_2_4_8.cc
+ internal/ceres/generated/schur_eliminator_2_4_9.cc
+ internal/ceres/generated/schur_eliminator_2_4_d.cc
+ internal/ceres/generated/schur_eliminator_2_d_d.cc
+ internal/ceres/generated/schur_eliminator_4_4_2.cc
+ internal/ceres/generated/schur_eliminator_4_4_3.cc
+ internal/ceres/generated/schur_eliminator_4_4_4.cc
+ internal/ceres/generated/schur_eliminator_4_4_d.cc
+ )
+else()
+ add_definitions(-DCERES_RESTRICT_SCHUR_SPECIALIZATION)
+endif()
if(WIN32)
list(APPEND INC
@@ -307,7 +326,6 @@ add_definitions(
-DCERES_NO_SUITESPARSE
-DCERES_NO_CXSPARSE
-DCERES_NO_LAPACK
- -DCERES_RESTRICT_SCHUR_SPECIALIZATION
-DCERES_HAVE_RWLOCK
)
diff --git a/extern/libmv/third_party/ceres/ChangeLog b/extern/libmv/third_party/ceres/ChangeLog
index c9f5b3426bc..6f921542019 100644
--- a/extern/libmv/third_party/ceres/ChangeLog
+++ b/extern/libmv/third_party/ceres/ChangeLog
@@ -1,646 +1,671 @@
-commit 8c62487e437b91d3d354cd1ae8957e43fe540732
+commit 9e11cd16d09403b9270e621e839d5948b6a74b8d
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri May 16 09:44:18 2014 -0700
+Date: Mon Sep 29 14:27:58 2014 -0700
- Preparations for 1.9.0 release.
+ Faster BlockRandomAccessSparseMatrix::SymmetricRightMultiply.
- Version bump.
- minor docs update.
+ Trade a small amount of memory to improve the cache coherency of
+ the SymmetricRightMultiply operation.
- Change-Id: I2fbe20ba4af6b2e186fe244c96ce6d6464fe0469
+ The resulting code leads to a 10-20% speedup in the linear solver
+ end to end.
+
+ Change-Id: I8ab2fe152099e849b211b5b19e4ef9f03d8e7f1c
-commit 0831275a78ab65e4c95979598cb35c54d03d3185
+commit 46b8461fd010c1e7ffce6bb2bdf8a84b659d5e09
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri May 16 08:17:54 2014 -0700
+Date: Mon Sep 29 15:10:58 2014 -0700
- Documentation update.
-
- 1. Update iOS build instructions.
- 2. Update version history.
+ Various minor fixes from William Rucklidge.
- Change-Id: I49d62e86ecff39190b50c050cb12eef4e2773357
+ Change-Id: Ibe731d5db374ad8ee148d62a9fdd8d726b607a3f
-commit c7c7458625996a20203f1366d11bd701e5fb621b
-Author: Jack Feng <jackfengji@gmail.com>
-Date: Mon May 12 10:23:56 2014 +0800
+commit b44cfdef25f6bf0917a23b3fd65cce38aa6a3362
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Mon Sep 29 07:53:54 2014 -0700
- add support for building for ios
+ Let ITERATIVE_SCHUR use an explicit Schur Complement matrix.
- use ios-cmake to build for ios
+ Up till now ITERATIVE_SCHUR evaluates matrix-vector products
+ between the Schur complement and a vector implicitly by exploiting
+ the algebraic expression for the Schur complement.
- Change-Id: I6b17c33339f3121322a4004d79629b22a62f7a94
-
-commit 36c2ce87d13b9b7123bd0473b8b45fb3b6ae4271
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Mon Jan 13 21:18:08 2014 +0600
-
- Libmv 2D homography estimation example application
+ This cost of this evaluation scales with the number of non-zeros
+ in the Jacobian.
+
+ For small to medium sized problems there is a sweet spot where
+ computing the Schur complement is cheap enough that it is much
+ more efficient to explicitly compute it and use it for evaluating
+ the matrix-vector products.
+
+ This changes implements support for an explicit Schur complement
+ in ITERATIVE_SCHUR in combination with the SCHUR_JACOBI preconditioner.
+
+ API wise a new bool Solver::Options::use_explicit_schur_complement
+ has been added.
+
+ The implementation extends the SparseSchurComplementSolver to use
+ Conjugate Gradients.
+
+ Example speedup:
+
+ use_explicit_schur_complement = false
+
+ Time (in seconds):
+ Preprocessor 0.585
- Add an example application of homography matrix estimation
- from a 2D euclidean correspondences which is done in two
- steps:
+ Residual evaluation 0.319
+ Jacobian evaluation 1.590
+ Linear solver 25.685
+ Minimizer 27.990
- - Coarse algebraic estimation
- - Fine refinement using Ceres minimizer
+ Postprocessor 0.010
+ Total 28.585
- Nothing terribly exciting apart from an example of how to
- use user callbacks.
+ use_explicit_schur_complement = true
- User callback is used here to stop minimizer when average
- of symmetric geometric distance becomes good enough.
- This might be arguable whether it's the best way to go
- (in some cases you would want to stop minimizer when
- maximal symmetric distance is lower than a threshold) but
- for a callback usage example it's good enough to stick
- to current logic.
+ Time (in seconds):
+ Preprocessor 0.638
- Change-Id: I60c8559cb10b001a0eb64ab71920c08bd68455b8
+ Residual evaluation 0.318
+ Jacobian evaluation 1.507
+ Linear solver 5.930
+ Minimizer 8.144
+
+ Postprocessor 0.010
+ Total 8.791
+
+ Which indicates an end-to-end speedup of more than 3x, with the linear
+ solver being sped up by > 4x.
+
+ The idea to explore this optimization was inspired by the recent paper:
+
+ Mining structure fragments for smart bundle adjustment
+ L. Carlone, P. Alcantarilla, H. Chiu, K. Zsolt, F. Dellaert
+ British Machine Vision Conference, 2014
+
+ which uses a more complicated algorithm to compute parts of the
+ Schur complement to speed up the matrix-vector product.
+
+ Change-Id: I95324af0ab351faa1600f5204039a1d2a64ae61d
-commit d99a3a961e4a6ff7218d0ab749da57cf1a1677bd
-Author: Björn Piltz <bjornpiltz@gmail.com>
-Date: Wed May 7 14:59:12 2014 +0200
+commit 4ad91490827f2ebebcc70d17e63ef653bf06fd0d
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Wed Sep 24 23:54:18 2014 -0700
- Separate PUBLIC and PRIVATE library dependencies
- Do not propagate 3d party libs through
- IMPORTED_LINK_INTERFACE_LIBRARIES_[DEBUG/RELEASE] mechanism
- when building shared libraries. SuiteSparse, lapack & co
- are considered private. Glog still gets propagated since
- it is part of the public interface. See documentation of
- TARGET_LINK_LIBRARIES().
+ Simplify the Block Jacobi and Schur Jacobi preconditioners.
+
+ 1. Extend the implementation of BlockRandomAccessDiagonalMatrix
+ by adding Invert and RightMultiply methods.
- Change-Id: If0563b0c705b102876f5190e9a86694d10f79283
+ 2. Simplify the implementation of the Schur Jacobi preconditioner
+ using these new methods.
+
+ 3. Replace the custom storage used inside Block Jacobi preconditioner
+ with BlockRandomAccessDiagonalMatrix and simplify its implementation
+ too.
+
+ Change-Id: I9d4888b35f0f228c08244abbdda5298b3ce9c466
-commit 1c089e8453583876f417b214f76a5863d7694986
+commit 8f7be1036b853addc33224d97b92412b5a1281b6
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue May 13 16:58:25 2014 -0700
+Date: Mon Sep 29 08:13:35 2014 -0700
- Notational fix in modeling.rst by William Rucklidge.
+ Fix a formatting error TrustRegionMinimizer logging.
- Change-Id: Iffa127541380fcc32da13fe4ac474692e1e3d0ec
+ Change-Id: Iad1873c51eece46c3fdee1356d154367cfd7925e
-commit 082d9e2a1b43b26a81157a6c711de0ff34c40ba4
+commit c99872d48e322662ea19efb9010a62b7432687ae
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon May 12 20:41:27 2014 -0700
+Date: Wed Sep 24 21:30:02 2014 -0700
- Add iOS.cmake from the ios-cmake project.
-
- URL: https://github.com/cristeab/ios-cmake
- Commit: 86dc085f0d5ed955cd58e2657cc3efc7c1aabbc8
+ Add BlockRandomAccessSparseMatrix::SymmetricRightMultiply.
- Change-Id: I8fe6023d4cb6655b5a724e8b695fdae87ce3b685
+ Change-Id: Ib06a22a209b4c985ba218162dfb6bf46bd93169e
-commit a97056c9752fe7223c8560da58862ecb1fd241ad
+commit d3ecd18625ba260e0d00912a305a448b566acc59
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue May 13 16:45:36 2014 -0700
+Date: Tue Sep 23 10:12:42 2014 -0700
- Various documentation fixes from William Rucklidge.
+ Add an explicit include for local_parameterization.h
- Change-Id: I102e98f41f4b5fe2a84d1224d5ed7517fdfdb022
+ Thanks to cooordz for reporting this.
+
+ Change-Id: I7d345404e362a94ff1eb433ad6b9dcc4960ba76d
-commit 2f8fb218f0a08102231ace07ef02b34b4aad7336
+commit 5dd76869cf45122c79579423f09e0de08cf04092
Author: Alex Stewart <alexs.mac@gmail.com>
-Date: Tue May 13 20:57:39 2014 +0100
+Date: Fri Sep 19 16:08:25 2014 +0100
- Adding function to update CMake cache variables and preserve help.
+ Fix unused-function warning with Eigen < 3.2.2.
- - Previously we were replicating the same two lines to update a cache
- variable whilst preserving its help string.
- - This commit adds a function which wraps up this common operation into
- a single line.
+ - CreateBlockJacobian() is only ever used when Eigen >= 3.2.2 is
+ detected, but was previously defined whenever CERES_USE_EIGEN_SPARSE
+ was defined with no check on the Eigen version.
+ - This resulted in an unused-function compile warning that became an
+ error due to -Werror, preventing compilation when using Eigen < 3.2.2.
- Change-Id: Ic78a5adf5d59262bbbcec1e353ded7620391e862
+ Change-Id: I24628ff329f14b087ece66bf2626bdc0de4ba224
-commit 8f4dcb25f1be74a8c12c0f9eeb67b6b0755563f5
+commit 820cb7b14831aa03eca1e8186000cebfdf0a42f3
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue Apr 29 21:40:57 2014 -0700
+Date: Wed Sep 17 09:46:08 2014 -0700
- Documentation update.
-
- Update modeling.rst and solving.rst to reflect
- changes to the API.
+ Add solver_utils.cc to Android.mk
- Change-Id: Id1a8adfed1486f08e5fd67c5af2d29708a26490c
+ Change-Id: I358522971711280f4362a1fa39b1568160e21e63
-commit d48e7050225730f61eaef851def5b43bc439e991
-Author: Alex Stewart <alexs.mac@gmail.com>
-Date: Sat May 10 08:58:58 2014 +0100
+commit 092b94970a073f8b47179d96160226fc19095898
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Fri Sep 5 11:56:29 2014 -0700
- Configure config.h and include it from the build directory.
+ Add GradientProblem and GradientProblemSolver.
+
+ The line search minimizer in Ceres does not require that the
+ problems that is solving is a sum of squares. Over the past
+ year there have been multiple requests to expose this algorithm
+ on its own so that it can be used to solve unconstrained
+ non-linear minimization problems on its own.
+
+ With this change, a new optimization problem called
+ GradientProblem is introduced which is basically a thin
+ wrapper around a user defined functor that evaluates cost
+ and gradients (FirstOrderFunction) and an optional LocalParameterization.
- - Previously we overwrote the default (empty) config.h in the source
- tree with a configured config.h, generated using the current compile
- options.
- - This was undesirable as it could lead to inadvertant commits of the
- generated config.h.
+ Corresponding to it, a GradientProblemSolver and its associated
+ options and summary structs are introduced too.
- - This patch moves the default config.h to <src>/config/ceres/internal,
- separate from the other headers, thus if Ceres is compiled without
- CMake this directory will now also have to be included. This
- directory is _not_ added to the CMake include directories for Ceres
- (thus the default config.h is never used when compiling with CMake).
- - When using CMake, the generated config.h is now placed in
- <build>/config/ceres/internal, which is in turn added to the include
- directories for Ceres when it is compiled, and the resulting config.h
- is copied to ceres/internal when installed.
+ An example that uses the new API to find the minimum of Rosenbrock's
+ function is also added.
- Change-Id: Ib1ba45e66e383ade2ebb08603af9165c1df616f2
+ Change-Id: I42bf687540da25de991e9bdb00e321239244e8b4
-commit 11c496164ffe9809306945c2b81276efcd51533d
+commit 6c45d6b891aac01489b478a021f99081c61792cb
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri May 9 16:27:03 2014 -0700
+Date: Thu Sep 11 07:48:30 2014 -0700
- Fix 80cols violation in local_parameterization.h
+ Add more inspection methods to Problem.
- Change-Id: I07f59baa9e4aba7c5ae028f0c144ea9ad153d49a
+ Problem::GetCostFunctionForResidualBlock
+ Problem::GetLossFunctionForResidualBlock
+
+ are added, so that users do not have to maintain this mapping
+ outside the Problem.
+
+ Change-Id: I38356dfa094b2c7eec90651dafeaf3a33c5f5f56
-commit af3154422b63b7792ecd23b00ca1a0c003764dae
+commit 6ad9b8e2ae66c9009441d0f9304486ec8dfa9a6a
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri May 9 05:45:03 2014 -0700
+Date: Tue Sep 9 14:29:28 2014 -0700
- Add Alex Stewart as a maintainer.
+ Ignore row/column blocks structure when using dynamic sparsity
+
+ The row/column blocks can be huge when using dynamic sparsity. This
+ can result in very large memory usage when augmenting the jacobian
+ with the LM diagonal.
- Update contributing.rst to mention Alex
- as one of the people who can be added
- as a reviewer.
+ Thanks to Mingsong Dou for reporting this.
- Change-Id: I30ff3e635e8c419e11e8f20394aaea5f284a10d5
+ Change-Id: I6aa140ceefa98389ae17958f89ca76e0c76f95b8
-commit ea765850685f1ff0431da5212656378fc20d3673
-Author: Alex Stewart <alexs.mac@gmail.com>
-Date: Wed May 7 20:46:17 2014 +0100
-
- Adding autogenerated Ceres config.h to #define Ceres compile options.
-
- - Previously we passed all compile options to Ceres via add_definitions
- in CMake. This was fine for private definitions (used only by Ceres)
- but required additional work for public definitions to ensure they
- were correctly propagated to clients via CMake using
- target_compile_definitions() (>= 2.8.11) or add_definitions().
- - A drawback to these approaches is that they did not work for chained
- dependencies on Ceres, as in if in the users project B <- A <- Ceres,
- then although the required Ceres public compile definitions would
- be used when compiling A, they would not be propagated to B.
-
- - This patch replaces the addition of compile definitions via
- add_definitions() with an autogenerated config.h header which
- is installed with Ceres and defines all of the enabled Ceres compile
- options.
- - This removes the need for the user to propagate any compile
- definitions in their projects, and additionally allows post-install
- inspect of the options with which Ceres was compiled.
-
- Change-Id: Idbdb6abdad0eb31e7540370e301afe87a07f2260
-
-commit cbf955474acf8f275b272da6ff5acd3a629cc806
-Author: Björn Piltz <bjornpiltz@gmail.com>
-Date: Wed May 7 17:10:15 2014 +0200
+commit 7e43460d42e20be1ba13121655dbbfd0d1c751ae
+Author: Martin Baeuml <baeuml@gmail.com>
+Date: Mon Sep 8 16:49:06 2014 +0200
- Fixes swapped verboselevel and condition.
+ Fix a few typos in the documentation.
- Change-Id: I296d86e6bbf415be4bfd19d6a0fe0963e3d36d74
+ Change-Id: I541db56b2b81ae758e233ce850d78c3cbb4b6fa3
-commit 3209b045744ea31f38d74bd9e9c8f88e605e7f76
-Author: Björn Piltz <bjornpiltz@gmail.com>
-Date: Wed May 7 17:02:27 2014 +0200
+commit 1aef66eeae7042902655a11b0d6a1a32900abb7b
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Sun Sep 7 21:18:44 2014 -0700
- Fixed warning : 'va_copy' : macro redefinition
- MSVC 2013 has got va_copy
- Compare
- http://msdn.microsoft.com/en-us/library/kb57fad8(v=vs.110).aspx
- and
- http://msdn.microsoft.com/en-us/library/kb57fad8.aspx.
+ Remove errant space.
- Change-Id: If0937c76e8d250cde4b343844f3d35c980bf0921
+ Change-Id: Iedc06960417a9b938d57f623b4beb87a98e3d081
-commit 1df2f0f5d704f0cc458cf707e2602d495979e3c6
-Author: Björn Piltz <bjornpiltz@gmail.com>
-Date: Wed May 7 11:10:30 2014 +0200
+commit 89080ab153a33008782759187fa8e9af7d2f83f1
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Sat Sep 6 21:13:48 2014 -0700
- Removed MSVC warnings
- These are warnings which show up when using Ceres.
+ Add LocalParameterization::MultiplyByJacobian.
- Change-Id: Id1f382f46b8a60743f0b12535b5b3cdf46f988e0
+ This is needed to efficiently support LocalParameterization objects
+ in GradientProblemSolver.
+
+ Change-Id: Ic7b715b8be694b099dc95d6707a67474297533e6
-commit eca7e1c635581834c858794e09c1e876323b7775
+commit d76da16f49d419ae3664ca1bdc2286c1ea78ebed
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue May 6 10:16:19 2014 -0700
+Date: Sun Sep 7 18:42:49 2014 -0700
- Remove BlockRandomAccessCRSMatrix.
+ Move some routines to solver_utils.h/cc
- It is not used anywhere.
+ This moves a couple of routines from solver.cc into solver_utils.h/cc
+ so that they can also be used by the upcoming GradientProblemSolver.
- Change-Id: I2a8ebbdacf788582f21266825ead3f76646da29e
+ Change-Id: I627b32ad3dc639422aacde78a8e391459d947e99
-commit 7088a08f5d9e04e75a5a4c3823ef7927e13ff0e4
+commit cbf03ac292a0c0e9e6b7fcc1b08b67e95965922f
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon May 5 09:02:05 2014 -0700
+Date: Sat Sep 6 21:07:08 2014 -0700
- Fix some 80col violations and reflow the comments in cmake.in file.
+ Make LineSearchMinimizer consistent with TrustRegionMinimizer.
+
+ Change the logic for how IterationSummary objects are added to
+ Summary::iterations to match the one in TrustRegionMinimizer.
- Change-Id: I4c65c89b794845aeef69159a03350c727e2ee812
+ Change-Id: I57851ad8294e58f83b9115cca9c24695d86ee92a
-commit 95cce0834d5a2d72568e6d2be968a51c244c2787
+commit f04c32319751e1efd610acd3699bca0a6dd6c6d1
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon May 5 08:54:50 2014 -0700
+Date: Sat Sep 6 21:05:41 2014 -0700
- Remove some errant tabs.
+ Fix some obsolete documentation in CostFunction::Evaluate
- Change-Id: Ie1f7051e99bcb15ad068711b68a9d8f317b12ed7
+ Change-Id: I1d7ee5c596fbf6a4d886dce5b989c8eb18af2dce
-commit a536ae76dfa2dbe2bc487900b98cf6c15276c649
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Sun May 4 21:18:42 2014 -0700
+commit 9263547c02a1807532b159c217e7acd124d3db10
+Author: Johannes Schönberger <hannesschoenberger@gmail.com>
+Date: Sat Sep 6 17:26:15 2014 -0400
- Lazily initialize the bounds arrays in ParameterBlock.
+ Fix CG solver options for ITERATIVE_SCHUR, which did not copy min_num_iterations
- Problems that do not use bounds do not have to pay the
- price of storing bounds constraints.
+ Change-Id: If31bc53b49ec20426fd438b79b8fa1f69d11e861
+
+commit b41f048256d1a8184cbe874b5a96dffa7fa4630d
+Author: Martin Baeuml <baeuml@gmail.com>
+Date: Fri Sep 5 15:03:32 2014 +0200
+
+ Remove obsolete include of numeric_diff_functor.h.
- Also replace the raw pointer access to the upper and
- lower bounds arrays with accessors which hides the
- lazy initialization from the user.
+ numeric_diff_functor.h was removed and does not exist anymore.
- Change-Id: I0325a35de9c29f853559f891e32e7c777686e537
+ Change-Id: I07bf04bf81142551e867b95b83a0653e11cad54c
-commit 633b50b7af9841607c07133f585e131fba7de177
+commit b7fb6056a717cc3c372cfb7115c527ee8bc05ddb
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri May 2 22:46:20 2014 -0700
+Date: Wed Sep 3 11:19:02 2014 -0700
- Add the (2,4,8) template specialization.
+ Remove NumericDiffFunctor.
+
+ Its API was broken, and its implementation was an unnecessary
+ layer of abstraction over CostFunctionToFunctor.
- Change-Id: I058bcebdd1725031d573404133b184d6f27dc005
+ Change-Id: I18fc261fc6a3620b51a9eeb4dde0af03d753af69
-commit 5ffe06019a6c741ee7edc940ffeeceaaeabfa05d
-Author: Alex Stewart <alexs.mac@gmail.com>
-Date: Thu May 1 12:06:46 2014 +0100
+commit 175fa8ff09049110a8509409f60cee5fd52cdbe6
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Tue Sep 2 06:49:08 2014 -0700
- Export Ceres compile definitions to targets compiled against Ceres.
+ CostFunctionToFunctor allows dynamic number of residuals.
- - Previously all Ceres compile definitions were private to Ceres, that
- is they were not exported to users via the CMake export mechanism.
- - Now that we use compile definitions in public (installed) Ceres
- headers, we need to export the Ceres compile definitions.
- - If we did not do this, then the client's code 'see's' a different
- version of the Ceres headers to those which were in fact compiled,
- or in the case of shared_ptr, may not find the required header.
+ The code itself was perfectly capable of handling residuals, but there
+ was an overly strict runtime check that had to be removed.
- - This patch makes use of the new, in CMake 2.8.11, function:
- target_compile_definitions() to export all of the Ceres compile
- definitions using CMake's export functionality.
- - For CMake versions < 2.8.11, we have to use the blunter instrument of
- calling add_definitions() in CeresConfig.cmake (invoked by a call to
- find_package(Ceres)). This is messy because it ends up adding the
- Ceres compile definitions to any target declared in the user's code
- after the call to find_package(Ceres). Although this should do no
- harm as all of our defines are prefaced with CERES_, so any
- unintentional name clashes are unlikely.
+ Thanks to Domink Reitzle for reporting this.
- Change-Id: I5dea80949190eaf4fb08ea4ac568ce28c32dd4e0
+ Change-Id: I6a6d000a7c5203dd5945a61b4caeda1b8aeb09c9
-commit 0e811b0881f1f21df0ae04fd745ae4ba5189cac1
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Thu May 1 07:54:12 2014 -0700
+commit 70ace0d5a5601901288974fcf27919754260cf0e
+Author: Johannes Schönberger <hannesschoenberger@gmail.com>
+Date: Sat Aug 30 15:52:34 2014 -0400
- Fix a bug in Minimizer::RunCallbacks.
-
- Solver::Summary::message was not being updated when the solver
- terminated because of a user's iteration callback indicating
- success or failure.
-
- Thanks to Sergey Sharybin for reporting this.
+ Fix max. linear solver iterations in ConjugateGradientsSolver
- Change-Id: I27e6e5eed086920ddf765461b0159417ac79d7b3
+ Change-Id: Ice0cef46441dbc1c121eeb42113667a46c96936f
-commit 31b503792611d2119bb1acb3528fc8d58c5bd029
+commit c5d8d0680250f5eb554577d30d28fc805b03fab9
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Apr 30 15:02:38 2014 -0700
+Date: Fri Aug 29 20:31:19 2014 -0700
- Lint cleanup from William Rucklidge.
+ Fix a unused function error with Eigen version 3.2.1 or less.
+
+ Thanks to Johannes Schoenberger for reporting this.
- Change-Id: If545f114c1a2b07edd660a3c71ecfc16ffa25e43
+ Change-Id: Ie17d28f2a68734a978a8c95007724bc4055de43a
-commit 15c1210a8bdf3e936b4ef600d75f0fbb70878fb5
+commit 0e1cc2a55488e4cf381833baaa3531c02ce9d69e
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue Apr 29 08:12:19 2014 -0700
+Date: Fri Aug 29 09:16:56 2014 -0700
- Lint cleanup from Jim Roseborough.
+ Fix the build on Eigen version 3.2.1 and older.
- Change-Id: I53f4e0d020602443b397387b8c5908f25649403d
+ Change-Id: I18f5cb5d42113737d7b8f78a67acee28bd5b3e08
-commit b1668067f1c97520d5d28eecf2c11d2afc1b01b3
+commit 5f96c62b56222f27e606f2246a8a16b6942af8d1
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue Apr 29 08:12:19 2014 -0700
+Date: Thu Aug 28 23:06:17 2014 -0700
- Variety of changes to documentation and example code.
+ Add Block AMD ordering for SPARSE_SCHUR + EIGEN_SPARSE.
+
+ Ordering routines for the Schur complement when using EIGEN_SPARSE.
+ Also integration into SchurComplementSolver.
- 1. Update version history.
- 2. Minor changes to the tutorial to reflect the bounds constrained
- problem.
- 3. Added static factory methods to the SnavelyReprojectionError.
- 4. Removed relative gradient tolerance from types.h as it is
- not true anymore.
+ Part of this CL is also a refactoring of the block jacobian matrix
+ construction.
- Change-Id: I8de386e5278a008c84ef2d3290d2c4351417a9f1
+ Change-Id: I11d665cc7d4867c64190e6fed1118f4d2e13d59b
-commit 658407dacc351a999206980fbb3265099e50e7a3
+commit 7344626c04d19ca1dc4871c377c4422c744b1bca
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon Apr 28 13:25:17 2014 -0700
+Date: Thu Aug 28 22:03:09 2014 -0700
- Add missing template specializations to the NDK build.
+ Let EIGEN_SPARSE + SPARSE_NORMAL_CHOLESKY use block AMD.
- Change-Id: I42bb6c3bd47648050298472af80333aa900e79bf
-
-commit 5d7eed87b47871bc882af765188fa4fbca976855
-Author: Björn Piltz <bjornpiltz@gmail.com>
-Date: Wed Apr 23 22:13:37 2014 +0200
-
- Suppport for MSVC DLLs.
+ Modify SparseNormalCholeskySolver to use a pre-ordered Jacobian
+ matrix.
- Change-Id: Ibbcc4ba4e59f5bbf1cb91fe81c7d3b9042d03493
+ Change-Id: Ib4d725d7a2d7bb94ea76dbb3a9b172784dbc8ea0
-commit c830820a5c2be0d0cecb0822f2cff8b4ffe88f36
+commit 9f7032369ea4e432f0fb507cb6d2209741ee6946
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon Apr 28 10:28:24 2014 -0700
+Date: Thu Aug 28 21:46:43 2014 -0700
- Add missing files to Android.mk
+ Block AMD for SparseNormalCholesky + EIGEN_SPARSE.
- Change-Id: Ibdf577c592bcde0fe5c2ce343ed8e9028b82af8f
+ This is just the reordering routine. The integration with
+ SparseNormalCholesky shall happen in a subsequent CL.
+
+ Change-Id: I39ddc32aa66b11c368faf75404850fa0ae0d2b3a
-commit ceb7a3beaad140762b499f9a306fd7230715941a
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date: Mon Apr 28 13:50:09 2014 +0600
+commit b9331cd4077100d645be22a912d5743eeda72878
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Thu Aug 28 14:42:27 2014 -0700
- Fix compilation error when using G++ compiler
+ Cleanup reorder_program.cc
- This compiler defines shared_ptr in std::tr1 namespace, but
- for this <tr1/memory> is to be included. Further, this compiler
- also does have <memory> header which confused previous shared
- pointer check.
+ Program::SetParameterOffsetsAndIndex() was being called willy nilly.
+ Now the invariant is that any function that actually reorders the
+ program, updates the offsets and indices.
- Simplified logic around defines now, so currently we've got:
- - CERES_TR1_MEMORY_HEADER defined if <tr1/memory> is to be
- used for shared_ptr, otherwise <memory> is to be used.
- - CERES_TR1_SHARED_PTR defined if shared_ptr is defined in
- std::tr1 namespace, otherwise it's defined in std namespace.
+ Also the logic around handling EIGEN_SPARSE has been simplified in
+ anticipation of the block AMD code that is forthcoming.
- All the shared_ptr checks are now moved to own file FindSharedPtr
- which simplifies main CMakeLists.
+ Last but not the least, num_eliminate_blocks, which is a rather
+ cryptic name to begin with has been replaced by the more meaningful
+ size_of_first_elimination_group.
- Change-Id: I558a74793baaa0bd088801910a356be4ef17c31b
+ Change-Id: I77e684f699a93b53e76aa406d64f40f8704df813
-commit 02db9414fb6739857a37e268500083a0546cd0a3
+commit 79491a3f4a3939a3cce4644da7a998b7782b963a
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon Apr 28 08:32:51 2014 -0700
+Date: Thu Aug 28 13:57:50 2014 -0700
- Fix the documentation for RandNormal.
+ Solver::FullReport now reports build config.
+
+ The header of Summary::FullReport now looks like
- As pointed out by Jim Roseborough, this is the Marsaglia Polar
- method and not the Box-Muller method.
+ Solver Summary (v 1.10.0-suitesparse-cxsparse-lapack-no_openmp)
- Change-Id: Id5332bcd4b4c23a3885cc296729b44eaa5edd0a8
+ Original Reduced
+ Parameter blocks 22122 22122
+ Parameters 66462 66462
+ Residual blocks 83718 83718
+ Residual 167436 167436
+
+ Change-Id: Id1b81bbf90ba412d19e2dd3687eeb9d372b72c1b
-commit 32530788d08c53f8d2c8a5f9bd61aa60a23d6e03
-Author: Richard Stebbing <richie.stebbing@gmail.com>
-Date: Sat Apr 26 07:42:23 2014 +0100
+commit 48068c753e91d77f6c96ef2d529a27ef8ee3947c
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Thu Aug 28 13:03:40 2014 -0700
- Add dynamic_sparsity option.
-
- The standard sparse normal Cholesky solver assumes a fixed
- sparsity pattern which is useful for a large number of problems
- presented to Ceres. However, some problems are symbolically dense
- but numerically sparse i.e. each residual is a function of a
- large number of parameters but at any given state the residual
- only depends on a sparse subset of them. For these class of
- problems it is faster to re-analyse the sparsity pattern of the
- jacobian at each iteration of the non-linear optimisation instead
- of including all of the zero entries in the step computation.
+ Lint cleanup from William Rucklidge.
- The proposed solution adds the dynamic_sparsity option which can
- be used with SPARSE_NORMAL_CHOLESKY. A
- DynamicCompressedRowSparseMatrix type (which extends
- CompressedRowSparseMatrix) has been introduced which allows
- dynamic addition and removal of elements. A Finalize method is
- provided which then consolidates the matrix so that it can be
- used in place of a regular CompressedRowSparseMatrix. An
- associated jacobian writer has also been provided.
+ Change-Id: Ie0e0aa58440be7a4f67dcd633dbb6f1bb0c051a8
+
+commit 6a51b135e6298e8ba44a58cc2b54a170ab61a82f
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Thu Aug 28 10:48:29 2014 -0700
+
+ Fix solver_test.cc
- Changes that were required to make this extension were adding the
- SetMaxNumNonZeros method to CompressedRowSparseMatrix and adding
- a JacobianFinalizer template parameter to the ProgramEvaluator.
+ When Eigen is not installed, Solver::IsValid was not detecting
+ it correctly.
- Change-Id: Ia5a8a9523fdae8d5b027bc35e70b4611ec2a8d01
+ Change-Id: Id285a84d829a9e20bc5de663adfca66ac31e08f3
-commit 2569076ff0bf8ffb3938da8b5df7edc4883aa053
+commit 62a8d64453ee41dae56710a4eead3fadf2fe1a4e
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Apr 25 23:54:48 2014 -0700
+Date: Wed Aug 27 22:54:00 2014 -0700
- More NDK fixes.
+ Expand check for lack of a sparse linear algebra library.
- Fix variable names in port.h and fix fpclassify when
- using gnustl. This was tested by switching to gnustl
- in the JNI build.
+ The LinearSolver factory was creating a NULL linear solver
+ if only Eigen's sparse linear algebra backend was available.
- Thanks to Carlos Hernandez for suggesting the gnustl fixes.
+ Thanks to Michael Samples and Domink Reitzle for reporting this.
- Change-Id: I690b73caf495ccc79061f45288e416da1604cc72
+ Change-Id: I35e3a6c0fd0da2a31934adb5dfe4cad29577cc73
-commit e55596f8860a09b12b5e1f949237f15357c1ac59
+commit 12eb389b4ec4113a2260c1a192a1d3f8d1b6a2d3
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Apr 25 16:17:19 2014 -0700
+Date: Wed Aug 27 22:18:33 2014 -0700
- Change the defaults for shared_ptr.
+ Fix Eigen Row/ColMajor bug in NumericDiffCostFunction.
- By default shared_ptr is now assumed to be
- in the standard <memory> header and in the
- std namespace.
+ If the parameter block size is 1, asking Eigen to create
+ a row-major matrix triggers a compile time error. Previously
+ we were handling the case where the number of rows in the
+ jacobian block was known statically, but the problem is present
+ when the nummber of rows is dynamic.
- Previously the way the ifdefs were structured if the appropriate
- variable was not defined, it would default to <t1/memory>.
+ This CL fixes this problem.
- The new defaults are more future proof.
+ Thanks to Dominik Reitzle for reporting this.
- Change-Id: If457806191196be2b6425b8289ea7a3488a27445
+ Change-Id: I99c3eec3558e66ebf4efa51c4dee8ce292ffe0c1
-commit bb05be341b8436f611e4b69954a529edcca5b577
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Sun Apr 13 14:22:19 2014 -0700
+commit 6c25185bb1643d8d0f3d8e1a7b82a058156aa869
+Author: Alex Stewart <alexs.mac@gmail.com>
+Date: Thu Aug 28 16:07:51 2014 +0100
- Solver::Options uses shared_ptr to handle ownership.
+ Fix crash in Covariance if # threads > 1 requested without OpenMP.
- Solver::Options::linear_solver_ordering and
- Solver::Options::inner_iteration_ordering
- were bare pointers even though Solver::Options took ownership of these
- objects.
+ - Previously if options.num_threads > 1 was given to Covariance compiled
+ without OpenMP, a CHECK() would be triggered in program_evalutor.
- This lead to buggy user code and the inability to copy Solver::Options
- objects around.
-
- With this change, these naked pointers have been replaced by a
- shared_ptr object which will managed the lifetime of these objects. This
- also leads to simplification of the lifetime handling of these objects
- inside the solver.
+ Change-Id: Iaade4f5ed5326b0c59a7014c750c41ee026e1124
+
+commit 6f89d850fb4ace0104abccf467c4fe37ad378b79
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Wed Aug 27 11:51:50 2014 -0700
+
+ Further build breakage fixes.
- The Android.mk and Application.mk files have also been updated
- to use a newer NDK revision which ships with LLVM's libc++.
+ 1. Allow the minimum number of linear solver iterations to be zero.
+ 2. Fix conjugate gradients solver's iteration loop to be sane again.
- Change-Id: I25161fb3ddf737be0b3e5dfd8e7a0039b22548cd
+ Change-Id: I8594815fec940c2b30e28eb58ec5d8baacf13dae
-commit 8e0991381ea3a2baddea017cd07b333f0c5de595
-Author: Joydeep Biswas <joydeep.biswas@gmail.com>
-Date: Tue Apr 22 10:40:47 2014 -0400
+commit dd596d0f0d6d08951efc2c11a639b546db2080c6
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Wed Aug 27 11:26:50 2014 -0700
- Added a simplified robotics example for DynamicAutoDiffCostFunction.
+ Fix the broken build.
- Change-Id: I9520e0a9a8d9743285c5114523fbafa6ffa5b0bd
+ Change-Id: I083cf1cca1bf4cca956193022d450364e73f833a
-commit cc9d3bba1008066e51502cabd956985c6bdedfe8
+commit d906afae22b05b9b9a9a2657924f4c0bf1a9b5ea
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Apr 18 22:58:09 2014 -0700
+Date: Mon Aug 25 22:32:38 2014 -0700
- Remove a comment from conf.py
+ A number of bug fixes.
+
+ 1. Fix a build breakage in graph_test.
+ 2. Respect Solver::Options::min_num_linear_solver_iterations in
+ conjugate_gradients_solver.cc
- Change-Id: I675f7e8fc5dd2143eab74901bc7241e02e37285f
+ Thanks to Johannes Schönberger for reporting these.
+
+ Change-Id: Ib32e3929bf5d92dd576ae5b53d4d88797095136e
-commit c4cd29dd7c80ade5b3ac7a1f6ee7df22c8869ab5
+commit dab955928c6d0942d6acc5b5f1c4c11260d0767d
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Apr 16 23:40:12 2014 -0700
+Date: Sun Aug 17 13:14:50 2014 -0700
- Merge landing page with introduction.
+ Add an unweighted graph.
- The existing introduction was a bit redundant and also
- was not really an introduction. Also updated the build
- instructions to reflect the new reality on Mac OSX.
+ Rename Graph -> WeightedGraph.
+ Add a new Graph class, which is cheaper to construct and
+ work with if the weights are not needed.
- Also updated the beginning of the tutorial to be a bit
- gentler and updated the history to be more consistent
+ This cuts down the cost of building the Hessian graph
+ significantly.
- Change-Id: Ife38c1949252cf9f4c6301856957f2d38365f313
+ Change-Id: Id0cfc81dd2c0bb5ff8f63a1b55aa133c53c0c869
-commit 46ccfb376ac52ac159f9187e0f7384ef68c1cbdd
+commit a0c282adbd268c2ad82551fab31fe1cf8d0c4282
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Sat Apr 12 21:56:51 2014 -0700
+Date: Sun Aug 24 22:19:03 2014 -0700
- Cleanup block_structure.h/cc
+ Add EIGEN_STRONG_INLINE annotation to jet.h
- 1. Remove obsolete Proto conversion functions.
- 2. Fix a strict weak ordering bug.
+ This improves performance when using MSVC on Windows. On GCC
+ there will be no effect.
- Change-Id: I1ce6d4b06e29cf475df1d5bd37c79f66f20f8d93
+ Change-Id: I555a81ff6823c2855d64773073f75af50c48d716
-commit 7d489fdb073937ac05c0693c1902fbcb9eeb7dfc
-Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Mon Apr 7 11:14:51 2014 -0700
+commit 20de0a7793c574e964350a623446136889f74632
+Author: Björn Piltz <bjornpiltz@gmail.com>
+Date: Mon Aug 25 17:05:54 2014 +0200
- Refactor the landing page to be a bit more compact.
+ Fixed Malformed regex
- Also minor changes to the introduction.
+ I got the following error with MSVC:
+ Syntax error at index 9 in simple regular expression "NumGroups()": '(' is unsupported.
- Change-Id: Iaa71f576b95c869f075d6837dbb60ba4bb608ee7
+ Change-Id: Id1952831d81d3eb5d73bbed8c311914c4c8ab51f
-commit 406ac7816730c15425db20d994ac0d60d932ab6c
-Author: Keir Mierle <mierle@gmail.com>
-Date: Mon Apr 7 08:36:07 2014 +0000
+commit ccf8aea988269841d84d746e52164d5056c67a10
+Author: Björn Piltz <bjornpiltz@gmail.com>
+Date: Mon Aug 25 16:16:01 2014 +0200
- Rework Ceres documentation as new website
+ Fixed MSVC error C2124: divide or mod by zero
- This reworks the Ceres Sphinx documentation such that it can
- function as the main Ceres website, now hosted at
- ceres-solver.org. This also changes to the theme sphinx_rtd_theme
- used by Read The Docs; this theme has strong mobile support and is
- well enough designed.
+ Alternatively, if quiet_NaN is not available on all platforms a workaround would be:
+ volatile double zero = 0.0;
+ double x = 1.0/zero;
+ The 'volatile' is needed to shut up "warning C4723: potential divide by 0".
- Change-Id: I63232d985859a6dac94ff58f08bf81eb2b9e7f99
+ Change-Id: If2bbdab8540595aa2e0079e1eb6b6fed6d4a6ef7
-commit 3e60a998ac970da659d590bac2ff892ee619aa1b
-Author: Richard Bowen <rsbowen@google.com>
-Date: Tue Apr 1 16:22:49 2014 -0700
+commit 8de27be218d42b282d7f15867733ad07058b0887
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Tue Aug 19 08:22:40 2014 -0700
- Added support and tests: row and column blocks for sparse matrix
- transpose.
+ Fix a bug in TrustRegionPreprocessor
+
+ TrustRegionPreprocessor was not setting Minimizer::Options::is_constrained.
+ This meant that the line search for bounds constraints was not being
+ invoked for bounds constrained problems.
- Change-Id: Ife641b08a9e86826478521a405f21ba60667f0e8
+ And some minor lint cleanup.
+
+ Change-Id: I18852cfaf1b33fd90b7d8c196f2063c128126658
-commit 5ecb1c3f1dfde6e8ed4b493eafef7b43dad19e72
+commit 1745dd615b3897a3ef9896acfdba67eee1739bf4
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Tue Apr 1 09:20:35 2014 -0700
+Date: Thu Jun 5 21:30:13 2014 -0700
- Add Problem::IsParameterBlockPresent.
+ Refactor SolverImpl.
+
+ Replace SolverImpl with
+
+ a. A minimizer specific preprocessor class.
+ b. A generic Solve function inside solver.cc
+ c. Presummarize and Postsummarize functions to handle
+ updates to the summary object.
- This allows the user to query the Problem to see if a
- parameter block is already present or not.
+ The existing SolverImpl class was a mixture of the above three
+ things and was increasingly complicated code to follow. This change,
+ breaks it into its three separate constituents, with the aims of
+ better separation of concerns and thus better testability and
+ reliability.
- Change-Id: If786f6c008cc644f3398597901d718d12a6d865d
+ The call to Solver::Solve() now consists of
+
+ 1. Presummarize - summarize the given state of the problem and solver
+ options.
+ 2. Preprocess - Setup everything that is needed to call the minimizer.
+ This includes, removing redundant parameter and residual blocks,
+ setting up the reordering for the linear solver, creating the
+ linear solver, evaluator, inner iteration minimizer etc.
+ 3. Minimize.
+ 4. Post summarize - summarize the result of the preprocessing and the
+ solve.
+
+ Change-Id: I80f35cfc9f2cbf78f1df4aceace27075779d8a3a
-commit 75e2232b29ff2ea42c8406c9d45b138a7e7a0048
+commit bd90384226a7f8629467f72fc410a9e8086a2dff
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Fri Mar 28 11:21:02 2014 -0700
+Date: Mon Aug 18 11:27:06 2014 -0700
- Fix spacing in building.rst
+ Lint comments from William Rucklidge.
+
+ Also some minor refactoring of the trust_region_preprocessor_test.cc
- Change-Id: I4c68d732c80d7ff2bdbc812bf0b7c7fb98c43957
+ Change-Id: Ica28002254c95722faf93a7ef35bf3deab557f0b
-commit b555b489b8447434294a8a6676272289140d6a1d
-Author: Richard Bowen <rsbowen@google.com>
-Date: Thu Mar 27 15:51:28 2014 -0700
+commit 3150321db4a0cb1bb4894961a030d95dacae3591
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Tue Aug 12 22:46:51 2014 -0700
- Changes documentation to reflect changes in output format.
+ Preprocessor for the LineSearchMinimizer.
- Change-Id: Ic0ba234283e791edcad29aec067905dcb2130813
+ Change-Id: Ieb5dfe1c0b96ef323c1130edd0c3a8a8b2c644cc
-commit 1cfb600bfc3be8342f85f155b2b219a595ee58da
+commit f7da411ef0d0067e269629887d64cdb769368800
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Mar 26 12:55:11 2014 -0700
+Date: Thu Aug 7 14:30:33 2014 -0700
- Add the (2,4,9) template specialization for PartitionedMatrixView
- and SchurEliminator.
+ Preprocessor for the TrustRegionMinimizer.
- Also update the comment inside generate_partitioned_matrix_view_specializations.py
+ 1. Base class for preprocessors.
+ 2. A preprocessor for problems that will be solved using
+ the trust region minimizer.
+ 3. Added sanity tests to the program reordering options
+ for Schur type linear solvers.
+ 4. Tests for the TrustRegionPreprocessor.
- Change-Id: I99a7ab4256091b1da48553da3076e5996a5757ed
+ Change-Id: I88cd926f0053bbbf2bd6b11e03ec55b8bf473cf1
-commit 195e49351b386ffc23020d406883eaa6511e29b3
+commit 54893ba523106e38ab06eb72fb5d8748685c7797
Author: Alex Stewart <alexs.mac@gmail.com>
-Date: Wed Mar 26 11:36:11 2014 +0000
+Date: Mon Aug 11 19:04:18 2014 +0100
- Check validity of residual block before removal in RemoveResidualBlock.
-
- - Breaking change: Problem::Options::enable_fast_parameter_block_removal
- is now Problem::Options::enable_fast_removal, as it now controls
- the behaviour for both parameter and residual blocks.
-
- - Previously we did not check that the specified residual block to
- remove in RemoveResidualBlock actually represented a valid residual
- for the problem.
- - This meant that Ceres would die unexpectedly if the user passed an
- uninitialised residual_block, or more likely attempted to remove a
- residual block that had already been removed automatically after
- the user removed a parameter block upon on which it was dependent.
- - RemoveResidualBlock now verifies the validity of the given
- residual_block to remove. Either by checking against a hash set of
- all residuals maintained in ProblemImpl iff enable_fast_removal
- is enabled. Or by a full scan of the residual blocks if not.
+ Add missing #include of <limits> for loss functions.
- Change-Id: I9ab178e2f68a74135f0a8e20905b16405c77a62b
+ Change-Id: Id632451429e03031a1533a9be795270debc70706
-commit 74762b60332d4a1c08ec5aef75ec718da9d305a2
-Author: Alex Stewart <alexs.mac@gmail.com>
-Date: Thu Mar 20 14:50:25 2014 +0000
+commit 4a2a888905fd1ce7203e45df15762d52740bb240
+Author: Sameer Agarwal <sameeragarwal@google.com>
+Date: Thu Aug 7 11:48:03 2014 -0700
- Allow construction of an AutoDiffLocalParameterization with a functor.
+ Change ownership of pointers in Minimizer::Options.
+
+ This is a intermediate change to clean things up
+ in preparation for a broader refactoring of the SolverImpl.
- - Previously AutoDiffLocalParameterization would internally instantiate
- a functor instance whenever one was required. This prohibits the
- user passing arguments to the constructor of the functor.
- - Now AutoDiffLocalParameterization can take over ownership of an
- allocated functor which the user created. This mimics the behaviour
- of AutoDiffCostFunction.
+ Essentially we are replacing raw pointers in Minimizer::Options
+ with shared_ptr objects. For now this only makes things a bit
+ more complicated looking inside solver_impl.cc, but going
+ forward this will lead to considerable simplifications in
+ tracking ownership of various pointers.
- Change-Id: I264e1face44ca5d5e71cc20c77cc7654d3f74cc0
+ Change-Id: I21db8fc6763c29b0d15e834d7c968a0f514042a0
-commit 4f603fb0d82317a53fa9d96abe6a97b2e69bff36
+commit 0d4e3bd664d442b700fee2895c7a8ac37717dc08
Author: Sameer Agarwal <sameeragarwal@google.com>
-Date: Wed Mar 19 17:16:43 2014 -0700
+Date: Thu Aug 7 12:19:10 2014 -0700
- Grammer fixes from William Rucklidge.
+ GradientCheckingProblem's parameter blocks are initialized correctly.
+
+ Ensure that when a new problem object is constructed for validing
+ gradients, the parameter blocks have their data pointers point to
+ the user's parameter blocks.
+
+ We used to do this inside solver_impl.cc, but doing this at
+ construction is the right thing to do.
- Change-Id: Ia40df7a1d141eb2552694510453d1431bb0c8dce
+ Change-Id: I3bfdc89bb0027c8d67cde937e8f2fa385d89c30c
diff --git a/extern/libmv/third_party/ceres/SConscript b/extern/libmv/third_party/ceres/SConscript
index 573157cb770..f53d54ba94b 100644
--- a/extern/libmv/third_party/ceres/SConscript
+++ b/extern/libmv/third_party/ceres/SConscript
@@ -13,15 +13,17 @@ src = []
defs = []
src += env.Glob('internal/ceres/*.cc')
-src += env.Glob('internal/ceres/generated/schur_eliminator_d_d_d.cc')
-src += env.Glob('internal/ceres/generated/partitioned_matrix_view_d_d_d.cc')
-#src += env.Glob('internal/ceres/generated/*.cc')
+if env['WITH_BF_LIBMV_SCHUR_SPECIALIZATIONS']:
+ src += env.Glob('internal/ceres/generated/*.cc')
+else:
+ src += env.Glob('internal/ceres/generated/schur_eliminator_d_d_d.cc')
+ src += env.Glob('internal/ceres/generated/partitioned_matrix_view_d_d_d.cc')
+ defs.append('CERES_RESTRICT_SCHUR_SPECIALIZATION')
defs.append('CERES_HAVE_PTHREAD')
defs.append('CERES_NO_SUITESPARSE')
defs.append('CERES_NO_CXSPARSE')
defs.append('CERES_NO_LAPACK')
-defs.append('CERES_RESTRICT_SCHUR_SPECIALIZATION')
defs.append('CERES_HAVE_RWLOCK')
if env['WITH_BF_OPENMP']:
@@ -50,11 +52,6 @@ if env['SHARED_PTR_NAMESPACE'] == 'std::tr1':
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags ./config'
-# work around broken hashtable in 10.5 SDK
-if env['OURPLATFORM'] == 'darwin' and env['WITH_BF_BOOST']:
- incs += ' ' + env['BF_BOOST_INC']
- defs.append('CERES_HASH_BOOST')
-
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
incs += ' ../msinttypes'
diff --git a/extern/libmv/third_party/ceres/bundle.sh b/extern/libmv/third_party/ceres/bundle.sh
index e7239d9a823..51a463a18ad 100755
--- a/extern/libmv/third_party/ceres/bundle.sh
+++ b/extern/libmv/third_party/ceres/bundle.sh
@@ -46,7 +46,7 @@ rm -rf $tmp
sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t/' | \
grep -v -E 'schur_eliminator_[0-9]_[0-9d]_[0-9d].cc' | \
grep -v -E 'partitioned_matrix_view_[0-9]_[0-9d]_[0-9d].cc' | sort -d`
-generated_sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//#\t\t/' | \
+generated_sources=`find ./include ./internal -type f -iname '*.cc' -or -iname '*.cpp' -or -iname '*.c' | sed -r 's/^\.\//\t\t/' | \
grep -E 'schur_eliminator_[0-9]_[0-9d]_[0-9d].cc|partitioned_matrix_view_[0-9]_[0-9d]_[0-9d].cc' | sort -d`
headers=`find ./include ./internal -type f -iname '*.h' | sed -r 's/^\.\//\t/' | sort -d`
@@ -138,11 +138,13 @@ ${sources}
${headers}
)
-#if(FALSE)
-# list(APPEND SRC
+if(WITH_LIBMV_SCHUR_SPECIALIZATIONS)
+ list(APPEND SRC
${generated_sources}
-# )
-#endif()
+ )
+else()
+ add_definitions-DCERES_RESTRICT_SCHUR_SPECIALIZATION)
+endif()
if(WIN32)
list(APPEND INC
@@ -165,7 +167,6 @@ add_definitions(
-DCERES_NO_SUITESPARSE
-DCERES_NO_CXSPARSE
-DCERES_NO_LAPACK
- -DCERES_RESTRICT_SCHUR_SPECIALIZATION
-DCERES_HAVE_RWLOCK
)
@@ -215,15 +216,17 @@ src = []
defs = []
$src
-src += env.Glob('internal/ceres/generated/schur_eliminator_d_d_d.cc')
-src += env.Glob('internal/ceres/generated/partitioned_matrix_view_d_d_d.cc')
-#src += env.Glob('internal/ceres/generated/*.cc')
+if env['WITH_BF_LIBMV_SCHUR_SPECIALIZATIONS']:
+ src += env.Glob('internal/ceres/generated/*.cc')
+else:
+ src += env.Glob('internal/ceres/generated/schur_eliminator_d_d_d.cc')
+ src += env.Glob('internal/ceres/generated/partitioned_matrix_view_d_d_d.cc')
+ defs.append('CERES_RESTRICT_SCHUR_SPECIALIZATION')
defs.append('CERES_HAVE_PTHREAD')
defs.append('CERES_NO_SUITESPARSE')
defs.append('CERES_NO_CXSPARSE')
defs.append('CERES_NO_LAPACK')
-defs.append('CERES_RESTRICT_SCHUR_SPECIALIZATION')
defs.append('CERES_HAVE_RWLOCK')
if env['WITH_BF_OPENMP']:
@@ -252,11 +255,6 @@ if env['SHARED_PTR_NAMESPACE'] == 'std::tr1':
incs = '. ../../ ../../../Eigen3 ./include ./internal ../gflags ./config'
-# work around broken hashtable in 10.5 SDK
-if env['OURPLATFORM'] == 'darwin' and env['WITH_BF_BOOST']:
- incs += ' ' + env['BF_BOOST_INC']
- defs.append('CERES_HASH_BOOST')
-
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
incs += ' ../msinttypes'
diff --git a/extern/libmv/third_party/ceres/files.txt b/extern/libmv/third_party/ceres/files.txt
index 164681d4d34..d1bd69672c8 100644
--- a/extern/libmv/third_party/ceres/files.txt
+++ b/extern/libmv/third_party/ceres/files.txt
@@ -11,13 +11,17 @@ include/ceres/dynamic_autodiff_cost_function.h
include/ceres/dynamic_numeric_diff_cost_function.h
include/ceres/fpclassify.h
include/ceres/gradient_checker.h
+include/ceres/gradient_problem.h
+include/ceres/gradient_problem_solver.h
include/ceres/internal/autodiff.h
+include/ceres/internal/disable_warnings.h
include/ceres/internal/eigen.h
include/ceres/internal/fixed_array.h
include/ceres/internal/macros.h
include/ceres/internal/manual_constructor.h
include/ceres/internal/numeric_diff.h
include/ceres/internal/port.h
+include/ceres/internal/reenable_warnings.h
include/ceres/internal/scoped_ptr.h
include/ceres/internal/variadic_evaluate.h
include/ceres/iteration_callback.h
@@ -26,13 +30,13 @@ include/ceres/local_parameterization.h
include/ceres/loss_function.h
include/ceres/normal_prior.h
include/ceres/numeric_diff_cost_function.h
-include/ceres/numeric_diff_functor.h
include/ceres/ordered_groups.h
include/ceres/problem.h
include/ceres/rotation.h
include/ceres/sized_cost_function.h
include/ceres/solver.h
include/ceres/types.h
+include/ceres/version.h
internal/ceres/array_utils.cc
internal/ceres/array_utils.h
internal/ceres/blas.cc
@@ -55,6 +59,8 @@ internal/ceres/block_sparse_matrix.cc
internal/ceres/block_sparse_matrix.h
internal/ceres/block_structure.cc
internal/ceres/block_structure.h
+internal/ceres/callbacks.cc
+internal/ceres/callbacks.h
internal/ceres/canonical_views_clustering.cc
internal/ceres/canonical_views_clustering.h
internal/ceres/c_api.cc
@@ -62,7 +68,6 @@ internal/ceres/casts.h
internal/ceres/cgnr_linear_operator.h
internal/ceres/cgnr_solver.cc
internal/ceres/cgnr_solver.h
-internal/ceres/CMakeLists.txt
internal/ceres/collections_port.h
internal/ceres/compressed_col_sparse_matrix_utils.cc
internal/ceres/compressed_col_sparse_matrix_utils.h
@@ -145,6 +150,9 @@ internal/ceres/generate_eliminator_specialization.py
internal/ceres/generate_partitioned_matrix_view_specializations.py
internal/ceres/gradient_checking_cost_function.cc
internal/ceres/gradient_checking_cost_function.h
+internal/ceres/gradient_problem.cc
+internal/ceres/gradient_problem_evaluator.h
+internal/ceres/gradient_problem_solver.cc
internal/ceres/graph_algorithms.h
internal/ceres/graph.h
internal/ceres/implicit_schur_complement.cc
@@ -170,6 +178,8 @@ internal/ceres/line_search_direction.h
internal/ceres/line_search.h
internal/ceres/line_search_minimizer.cc
internal/ceres/line_search_minimizer.h
+internal/ceres/line_search_preprocessor.cc
+internal/ceres/line_search_preprocessor.h
internal/ceres/local_parameterization.cc
internal/ceres/loss_function.cc
internal/ceres/low_rank_inverse_hessian.cc
@@ -189,6 +199,8 @@ internal/ceres/polynomial.cc
internal/ceres/polynomial.h
internal/ceres/preconditioner.cc
internal/ceres/preconditioner.h
+internal/ceres/preprocessor.cc
+internal/ceres/preprocessor.h
internal/ceres/problem.cc
internal/ceres/problem_impl.cc
internal/ceres/problem_impl.h
@@ -196,6 +208,8 @@ internal/ceres/program.cc
internal/ceres/program_evaluator.h
internal/ceres/program.h
internal/ceres/random.h
+internal/ceres/reorder_program.cc
+internal/ceres/reorder_program.h
internal/ceres/residual_block.cc
internal/ceres/residual_block.h
internal/ceres/residual_block_utils.cc
@@ -213,8 +227,8 @@ internal/ceres/single_linkage_clustering.cc
internal/ceres/single_linkage_clustering.h
internal/ceres/small_blas.h
internal/ceres/solver.cc
-internal/ceres/solver_impl.cc
-internal/ceres/solver_impl.h
+internal/ceres/solver_utils.cc
+internal/ceres/solver_utils.h
internal/ceres/sparse_matrix.cc
internal/ceres/sparse_matrix.h
internal/ceres/sparse_normal_cholesky_solver.cc
@@ -230,6 +244,8 @@ internal/ceres/triplet_sparse_matrix.cc
internal/ceres/triplet_sparse_matrix.h
internal/ceres/trust_region_minimizer.cc
internal/ceres/trust_region_minimizer.h
+internal/ceres/trust_region_preprocessor.cc
+internal/ceres/trust_region_preprocessor.h
internal/ceres/trust_region_strategy.cc
internal/ceres/trust_region_strategy.h
internal/ceres/types.cc
diff --git a/extern/libmv/third_party/ceres/include/ceres/c_api.h b/extern/libmv/third_party/ceres/include/ceres/c_api.h
index 632542e9bdd..71f41fd226b 100644
--- a/extern/libmv/third_party/ceres/include/ceres/c_api.h
+++ b/extern/libmv/third_party/ceres/include/ceres/c_api.h
@@ -39,6 +39,7 @@
#define CERES_PUBLIC_C_API_H_
#include "ceres/internal/port.h"
+#include "ceres/internal/disable_warnings.h"
#ifdef __cplusplus
extern "C" {
@@ -140,4 +141,6 @@ CERES_EXPORT void ceres_solve(ceres_problem_t* problem);
}
#endif
+#include "ceres/internal/reenable_warnings.h"
+
#endif /* CERES_PUBLIC_C_API_H_ */
diff --git a/extern/libmv/third_party/ceres/include/ceres/ceres.h b/extern/libmv/third_party/ceres/include/ceres/ceres.h
index acb402c542d..7c8981e2994 100644
--- a/extern/libmv/third_party/ceres/include/ceres/ceres.h
+++ b/extern/libmv/third_party/ceres/include/ceres/ceres.h
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2014 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -34,9 +34,6 @@
#ifndef CERES_PUBLIC_CERES_H_
#define CERES_PUBLIC_CERES_H_
-#define CERES_VERSION 1.9.0
-#define CERES_ABI_VERSION 1.9.0
-
#include "ceres/autodiff_cost_function.h"
#include "ceres/autodiff_local_parameterization.h"
#include "ceres/cost_function.h"
@@ -45,16 +42,18 @@
#include "ceres/crs_matrix.h"
#include "ceres/dynamic_autodiff_cost_function.h"
#include "ceres/dynamic_numeric_diff_cost_function.h"
+#include "ceres/gradient_problem.h"
+#include "ceres/gradient_problem_solver.h"
#include "ceres/iteration_callback.h"
#include "ceres/jet.h"
#include "ceres/local_parameterization.h"
#include "ceres/loss_function.h"
#include "ceres/numeric_diff_cost_function.h"
-#include "ceres/numeric_diff_functor.h"
#include "ceres/ordered_groups.h"
#include "ceres/problem.h"
#include "ceres/sized_cost_function.h"
#include "ceres/solver.h"
#include "ceres/types.h"
+#include "ceres/version.h"
#endif // CERES_PUBLIC_CERES_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h b/extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h
index 2a12ba6fe37..3f0087c7815 100644
--- a/extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h
+++ b/extern/libmv/third_party/ceres/include/ceres/conditioned_cost_function.h
@@ -39,6 +39,7 @@
#include "ceres/cost_function.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -93,5 +94,6 @@ class CERES_EXPORT ConditionedCostFunction : public CostFunction {
} // namespace ceres
+#include "ceres/internal/reenable_warnings.h"
#endif // CERES_PUBLIC_CONDITIONED_COST_FUNCTION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/cost_function.h b/extern/libmv/third_party/ceres/include/ceres/cost_function.h
index fee3e73c111..fe8fc07d2ce 100644
--- a/extern/libmv/third_party/ceres/include/ceres/cost_function.h
+++ b/extern/libmv/third_party/ceres/include/ceres/cost_function.h
@@ -48,6 +48,7 @@
#include "ceres/internal/macros.h"
#include "ceres/internal/port.h"
#include "ceres/types.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -105,8 +106,7 @@ class CERES_EXPORT CostFunction {
// the constraints, then returning false whenever the constraints
// are not satisfied will prevent the solver from moving into the
// infeasible region. This is not a very sophisticated mechanism for
- // enforcing constraints, but is often good enough for things like
- // non-negativity constraints.
+ // enforcing constraints, but is often good enough.
//
// Note that it is important that the initial values of the
// parameter block must be feasible, otherwise the solver will
@@ -142,4 +142,6 @@ class CERES_EXPORT CostFunction {
} // namespace ceres
+#include "ceres/internal/reenable_warnings.h"
+
#endif // CERES_PUBLIC_COST_FUNCTION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/cost_function_to_functor.h b/extern/libmv/third_party/ceres/include/ceres/cost_function_to_functor.h
index 0d01f772a3b..b4a516e0ab1 100644
--- a/extern/libmv/third_party/ceres/include/ceres/cost_function_to_functor.h
+++ b/extern/libmv/third_party/ceres/include/ceres/cost_function_to_functor.h
@@ -107,9 +107,7 @@ class CostFunctionToFunctor {
explicit CostFunctionToFunctor(CostFunction* cost_function)
: cost_function_(cost_function) {
CHECK_NOTNULL(cost_function);
-
- CHECK_GE(kNumResiduals, 0);
- CHECK_EQ(cost_function->num_residuals(), kNumResiduals);
+ CHECK(kNumResiduals > 0 || kNumResiduals == DYNAMIC);
// This block breaks the 80 column rule to keep it somewhat readable.
CHECK((!N1 && !N2 && !N3 && !N4 && !N5 && !N6 && !N7 && !N8 && !N9) ||
diff --git a/extern/libmv/third_party/ceres/include/ceres/covariance.h b/extern/libmv/third_party/ceres/include/ceres/covariance.h
index b6e9a6ae392..35fde4de05d 100644
--- a/extern/libmv/third_party/ceres/include/ceres/covariance.h
+++ b/extern/libmv/third_party/ceres/include/ceres/covariance.h
@@ -36,6 +36,7 @@
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -201,9 +202,9 @@ class CERES_EXPORT Covariance {
struct CERES_EXPORT Options {
Options()
#ifndef CERES_NO_SUITESPARSE
- : algorithm_type(SPARSE_QR),
+ : algorithm_type(SUITE_SPARSE_QR),
#else
- : algorithm_type(DENSE_SVD),
+ : algorithm_type(EIGEN_SPARSE_QR),
#endif
min_reciprocal_condition_number(1e-14),
null_space_rank(0),
@@ -228,47 +229,22 @@ class CERES_EXPORT Covariance {
// for small to moderate sized problems. It can handle
// full-rank as well as rank deficient Jacobians.
//
- // 2. SPARSE_CHOLESKY uses the CHOLMOD sparse Cholesky
- // factorization library to compute the decomposition :
- //
- // R'R = J'J
- //
- // and then
- //
- // [J'J]^-1 = [R'R]^-1
- //
- // It a fast algorithm for sparse matrices that should be used
- // when the Jacobian matrix J is well conditioned. For
- // ill-conditioned matrices, this algorithm can fail
- // unpredictabily. This is because Cholesky factorization is
- // not a rank-revealing factorization, i.e., it cannot reliably
- // detect when the matrix being factorized is not of full
- // rank. SuiteSparse/CHOLMOD supplies a heuristic for checking
- // if the matrix is rank deficient (cholmod_rcond), but it is
- // only a heuristic and can have both false positive and false
- // negatives.
- //
- // Recent versions of SuiteSparse (>= 4.2.0) provide a much
- // more efficient method for solving for rows of the covariance
- // matrix. Therefore, if you are doing SPARSE_CHOLESKY, we
- // strongly recommend using a recent version of SuiteSparse.
- //
- // 3. SPARSE_QR uses the SuiteSparseQR sparse QR factorization
- // library to compute the decomposition
+ // 2. EIGEN_SPARSE_QR uses the sparse QR factorization algorithm
+ // in Eigen to compute the decomposition
//
// Q * R = J
//
// [J'J]^-1 = [R*R']^-1
//
- // It is a moderately fast algorithm for sparse matrices, which
- // at the price of more time and memory than the
- // SPARSE_CHOLESKY algorithm is numerically better behaved and
- // is rank revealing, i.e., it can reliably detect when the
- // Jacobian matrix is rank deficient.
+ // It is a moderately fast algorithm for sparse matrices.
//
- // Neither SPARSE_CHOLESKY or SPARSE_QR are capable of computing
- // the covariance if the Jacobian is rank deficient.
-
+ // 3. SUITE_SPARSE_QR uses the SuiteSparseQR sparse QR
+ // factorization algorithm. It uses dense linear algebra and is
+ // multi threaded, so for large sparse sparse matrices it is
+ // significantly faster than EIGEN_SPARSE_QR.
+ //
+ // Neither EIGEN_SPARSE_QR not SUITE_SPARSE_QR are capable of
+ // computing the covariance if the Jacobian is rank deficient.
CovarianceAlgorithmType algorithm_type;
// If the Jacobian matrix is near singular, then inverting J'J
@@ -294,29 +270,13 @@ class CERES_EXPORT Covariance {
// where min_sigma and max_sigma are the minimum and maxiumum
// singular values of J respectively.
//
- // 2. SPARSE_CHOLESKY
- //
- // cholmod_rcond < min_reciprocal_conditioner_number
- //
- // Here cholmod_rcond is a crude estimate of the reciprocal
- // condition number of J'J by using the maximum and minimum
- // diagonal entries of the Cholesky factor R. There are no
- // theoretical guarantees associated with this test. It can
- // give false positives and negatives. Use at your own
- // risk. The default value of min_reciprocal_condition_number
- // has been set to a conservative value, and sometimes the
- // Covariance::Compute may return false even if it is possible
- // to estimate the covariance reliably. In such cases, the user
- // should exercise their judgement before lowering the value of
- // min_reciprocal_condition_number.
- //
- // 3. SPARSE_QR
+ // 2. SUITE_SPARSE_QR and EIGEN_SPARSE_QR
//
// rank(J) < num_col(J)
//
// Here rank(J) is the estimate of the rank of J returned by the
- // SuiteSparseQR algorithm. It is a fairly reliable indication
- // of rank deficiency.
+ // sparse QR factorization algorithm. It is a fairly reliable
+ // indication of rank deficiency.
//
double min_reciprocal_condition_number;
@@ -351,8 +311,8 @@ class CERES_EXPORT Covariance {
//
// lambda_i / lambda_max < min_reciprocal_condition_number.
//
- // This option has no effect on the SPARSE_CHOLESKY or SPARSE_QR
- // algorithms.
+ // This option has no effect on the SUITE_SPARSE_QR and
+ // EIGEN_SPARSE_QR algorithms.
int null_space_rank;
int num_threads;
@@ -419,4 +379,6 @@ class CERES_EXPORT Covariance {
} // namespace ceres
+#include "ceres/internal/reenable_warnings.h"
+
#endif // CERES_PUBLIC_COVARIANCE_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/crs_matrix.h b/extern/libmv/third_party/ceres/include/ceres/crs_matrix.h
index 687c9586dfd..d2d62894194 100644
--- a/extern/libmv/third_party/ceres/include/ceres/crs_matrix.h
+++ b/extern/libmv/third_party/ceres/include/ceres/crs_matrix.h
@@ -33,6 +33,7 @@
#include <vector>
#include "ceres/internal/port.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -80,4 +81,6 @@ struct CERES_EXPORT CRSMatrix {
} // namespace ceres
+#include "ceres/internal/reenable_warnings.h"
+
#endif // CERES_PUBLIC_CRS_MATRIX_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/gradient_problem.h b/extern/libmv/third_party/ceres/include/ceres/gradient_problem.h
new file mode 100644
index 00000000000..55a8be1df09
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/gradient_problem.h
@@ -0,0 +1,127 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#ifndef CERES_PUBLIC_GRADIENT_PROBLEM_H_
+#define CERES_PUBLIC_GRADIENT_PROBLEM_H_
+
+#include "ceres/internal/macros.h"
+#include "ceres/internal/port.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/local_parameterization.h"
+
+namespace ceres {
+
+class FirstOrderFunction;
+
+// Instances of GradientProblem represent general non-linear
+// optimization problems that must be solved using just the value of
+// the objective function and its gradient. Unlike the Problem class,
+// which can only be used to model non-linear least squares problems,
+// instances of GradientProblem not restricted in the form of the
+// objective function.
+//
+// Structurally GradientProblem is a composition of a
+// FirstOrderFunction and optionally a LocalParameterization.
+//
+// The FirstOrderFunction is responsible for evaluating the cost and
+// gradient of the objective function.
+//
+// The LocalParameterization is responsible for going back and forth
+// between the ambient space and the local tangent space. (See
+// local_parameterization.h for more details). When a
+// LocalParameterization is not provided, then the tangent space is
+// assumed to coincide with the ambient Euclidean space that the
+// gradient vector lives in.
+//
+// Example usage:
+//
+// The following demonstrate the problem construction for Rosenbrock's function
+//
+// f(x,y) = (1-x)^2 + 100(y - x^2)^2;
+//
+// class Rosenbrock : public ceres::FirstOrderFunction {
+// public:
+// virtual ~Rosenbrock() {}
+//
+// virtual bool Evaluate(const double* parameters,
+// double* cost,
+// double* gradient) const {
+// const double x = parameters[0];
+// const double y = parameters[1];
+//
+// cost[0] = (1.0 - x) * (1.0 - x) + 100.0 * (y - x * x) * (y - x * x);
+// if (gradient != NULL) {
+// gradient[0] = -2.0 * (1.0 - x) - 200.0 * (y - x * x) * 2.0 * x;
+// gradient[1] = 200.0 * (y - x * x);
+// }
+// return true;
+// };
+//
+// virtual int NumParameters() const { return 2; };
+// };
+//
+// ceres::GradientProblem problem(new Rosenbrock());
+class CERES_EXPORT GradientProblem {
+ public:
+ // Takes ownership of the function.
+ explicit GradientProblem(FirstOrderFunction* function);
+
+ // Takes ownership of the function and the parameterization.
+ GradientProblem(FirstOrderFunction* function,
+ LocalParameterization* parameterization);
+
+ int NumParameters() const;
+ int NumLocalParameters() const;
+
+ // This call is not thread safe.
+ bool Evaluate(const double* parameters, double* cost, double* gradient) const;
+ bool Plus(const double* x, const double* delta, double* x_plus_delta) const;
+
+ private:
+ internal::scoped_ptr<FirstOrderFunction> function_;
+ internal::scoped_ptr<LocalParameterization> parameterization_;
+ internal::scoped_array<double> scratch_;
+};
+
+// A FirstOrderFunction object implements the evaluation of a function
+// and its gradient.
+class CERES_EXPORT FirstOrderFunction {
+ public:
+ virtual ~FirstOrderFunction() {}
+ // cost is never NULL. gradient may be null.
+ virtual bool Evaluate(const double* const parameters,
+ double* cost,
+ double* gradient) const = 0;
+ virtual int NumParameters() const = 0;
+};
+
+} // namespace ceres
+
+#endif // CERES_PUBLIC_GRADIENT_PROBLEM_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/gradient_problem_solver.h b/extern/libmv/third_party/ceres/include/ceres/gradient_problem_solver.h
new file mode 100644
index 00000000000..484d88ece82
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/gradient_problem_solver.h
@@ -0,0 +1,365 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#ifndef CERES_PUBLIC_GRADIENT_PROBLEM_SOLVER_H_
+#define CERES_PUBLIC_GRADIENT_PROBLEM_SOLVER_H_
+
+#include <cmath>
+#include <string>
+#include <vector>
+#include "ceres/internal/macros.h"
+#include "ceres/internal/port.h"
+#include "ceres/iteration_callback.h"
+#include "ceres/types.h"
+#include "ceres/internal/disable_warnings.h"
+
+namespace ceres {
+
+class GradientProblem;
+
+class CERES_EXPORT GradientProblemSolver {
+ public:
+ virtual ~GradientProblemSolver();
+
+ // The options structure contains, not surprisingly, options that control how
+ // the solver operates. The defaults should be suitable for a wide range of
+ // problems; however, better performance is often obtainable with tweaking.
+ //
+ // The constants are defined inside types.h
+ struct CERES_EXPORT Options {
+ // Default constructor that sets up a generic sparse problem.
+ Options() {
+ line_search_direction_type = LBFGS;
+ line_search_type = WOLFE;
+ nonlinear_conjugate_gradient_type = FLETCHER_REEVES;
+ max_lbfgs_rank = 20;
+ use_approximate_eigenvalue_bfgs_scaling = false;
+ line_search_interpolation_type = CUBIC;
+ min_line_search_step_size = 1e-9;
+ line_search_sufficient_function_decrease = 1e-4;
+ max_line_search_step_contraction = 1e-3;
+ min_line_search_step_contraction = 0.6;
+ max_num_line_search_step_size_iterations = 20;
+ max_num_line_search_direction_restarts = 5;
+ line_search_sufficient_curvature_decrease = 0.9;
+ max_line_search_step_expansion = 10.0;
+ max_num_iterations = 50;
+ max_solver_time_in_seconds = 1e9;
+ num_threads = 1;
+ function_tolerance = 1e-6;
+ gradient_tolerance = 1e-10;
+ logging_type = PER_MINIMIZER_ITERATION;
+ minimizer_progress_to_stdout = false;
+ }
+
+ // Returns true if the options struct has a valid
+ // configuration. Returns false otherwise, and fills in *error
+ // with a message describing the problem.
+ bool IsValid(string* error) const;
+
+ // Minimizer options ----------------------------------------
+ LineSearchDirectionType line_search_direction_type;
+ LineSearchType line_search_type;
+ NonlinearConjugateGradientType nonlinear_conjugate_gradient_type;
+
+ // The LBFGS hessian approximation is a low rank approximation to
+ // the inverse of the Hessian matrix. The rank of the
+ // approximation determines (linearly) the space and time
+ // complexity of using the approximation. Higher the rank, the
+ // better is the quality of the approximation. The increase in
+ // quality is however is bounded for a number of reasons.
+ //
+ // 1. The method only uses secant information and not actual
+ // derivatives.
+ //
+ // 2. The Hessian approximation is constrained to be positive
+ // definite.
+ //
+ // So increasing this rank to a large number will cost time and
+ // space complexity without the corresponding increase in solution
+ // quality. There are no hard and fast rules for choosing the
+ // maximum rank. The best choice usually requires some problem
+ // specific experimentation.
+ //
+ // For more theoretical and implementation details of the LBFGS
+ // method, please see:
+ //
+ // Nocedal, J. (1980). "Updating Quasi-Newton Matrices with
+ // Limited Storage". Mathematics of Computation 35 (151): 773–782.
+ int max_lbfgs_rank;
+
+ // As part of the (L)BFGS update step (BFGS) / right-multiply step (L-BFGS),
+ // the initial inverse Hessian approximation is taken to be the Identity.
+ // However, Oren showed that using instead I * \gamma, where \gamma is
+ // chosen to approximate an eigenvalue of the true inverse Hessian can
+ // result in improved convergence in a wide variety of cases. Setting
+ // use_approximate_eigenvalue_bfgs_scaling to true enables this scaling.
+ //
+ // It is important to note that approximate eigenvalue scaling does not
+ // always improve convergence, and that it can in fact significantly degrade
+ // performance for certain classes of problem, which is why it is disabled
+ // by default. In particular it can degrade performance when the
+ // sensitivity of the problem to different parameters varies significantly,
+ // as in this case a single scalar factor fails to capture this variation
+ // and detrimentally downscales parts of the jacobian approximation which
+ // correspond to low-sensitivity parameters. It can also reduce the
+ // robustness of the solution to errors in the jacobians.
+ //
+ // Oren S.S., Self-scaling variable metric (SSVM) algorithms
+ // Part II: Implementation and experiments, Management Science,
+ // 20(5), 863-874, 1974.
+ bool use_approximate_eigenvalue_bfgs_scaling;
+
+ // Degree of the polynomial used to approximate the objective
+ // function. Valid values are BISECTION, QUADRATIC and CUBIC.
+ //
+ // BISECTION corresponds to pure backtracking search with no
+ // interpolation.
+ LineSearchInterpolationType line_search_interpolation_type;
+
+ // If during the line search, the step_size falls below this
+ // value, it is truncated to zero.
+ double min_line_search_step_size;
+
+ // Line search parameters.
+
+ // Solving the line search problem exactly is computationally
+ // prohibitive. Fortunately, line search based optimization
+ // algorithms can still guarantee convergence if instead of an
+ // exact solution, the line search algorithm returns a solution
+ // which decreases the value of the objective function
+ // sufficiently. More precisely, we are looking for a step_size
+ // s.t.
+ //
+ // f(step_size) <= f(0) + sufficient_decrease * f'(0) * step_size
+ //
+ double line_search_sufficient_function_decrease;
+
+ // In each iteration of the line search,
+ //
+ // new_step_size >= max_line_search_step_contraction * step_size
+ //
+ // Note that by definition, for contraction:
+ //
+ // 0 < max_step_contraction < min_step_contraction < 1
+ //
+ double max_line_search_step_contraction;
+
+ // In each iteration of the line search,
+ //
+ // new_step_size <= min_line_search_step_contraction * step_size
+ //
+ // Note that by definition, for contraction:
+ //
+ // 0 < max_step_contraction < min_step_contraction < 1
+ //
+ double min_line_search_step_contraction;
+
+ // Maximum number of trial step size iterations during each line search,
+ // if a step size satisfying the search conditions cannot be found within
+ // this number of trials, the line search will terminate.
+ int max_num_line_search_step_size_iterations;
+
+ // Maximum number of restarts of the line search direction algorithm before
+ // terminating the optimization. Restarts of the line search direction
+ // algorithm occur when the current algorithm fails to produce a new descent
+ // direction. This typically indicates a numerical failure, or a breakdown
+ // in the validity of the approximations used.
+ int max_num_line_search_direction_restarts;
+
+ // The strong Wolfe conditions consist of the Armijo sufficient
+ // decrease condition, and an additional requirement that the
+ // step-size be chosen s.t. the _magnitude_ ('strong' Wolfe
+ // conditions) of the gradient along the search direction
+ // decreases sufficiently. Precisely, this second condition
+ // is that we seek a step_size s.t.
+ //
+ // |f'(step_size)| <= sufficient_curvature_decrease * |f'(0)|
+ //
+ // Where f() is the line search objective and f'() is the derivative
+ // of f w.r.t step_size (d f / d step_size).
+ double line_search_sufficient_curvature_decrease;
+
+ // During the bracketing phase of the Wolfe search, the step size is
+ // increased until either a point satisfying the Wolfe conditions is
+ // found, or an upper bound for a bracket containing a point satisfying
+ // the conditions is found. Precisely, at each iteration of the
+ // expansion:
+ //
+ // new_step_size <= max_step_expansion * step_size.
+ //
+ // By definition for expansion, max_step_expansion > 1.0.
+ double max_line_search_step_expansion;
+
+ // Maximum number of iterations for the minimizer to run for.
+ int max_num_iterations;
+
+ // Maximum time for which the minimizer should run for.
+ double max_solver_time_in_seconds;
+
+ // Number of threads used by Ceres for evaluating the cost and
+ // jacobians.
+ int num_threads;
+
+ // Minimizer terminates when
+ //
+ // (new_cost - old_cost) < function_tolerance * old_cost;
+ //
+ double function_tolerance;
+
+ // Minimizer terminates when
+ //
+ // max_i |x - Project(Plus(x, -g(x))| < gradient_tolerance
+ //
+ // This value should typically be 1e-4 * function_tolerance.
+ double gradient_tolerance;
+
+ // Logging options ---------------------------------------------------------
+
+ LoggingType logging_type;
+
+ // By default the Minimizer progress is logged to VLOG(1), which
+ // is sent to STDERR depending on the vlog level. If this flag is
+ // set to true, and logging_type is not SILENT, the logging output
+ // is sent to STDOUT.
+ bool minimizer_progress_to_stdout;
+
+ // If true, the user's parameter blocks are updated at the end of
+ // every Minimizer iteration, otherwise they are updated when the
+ // Minimizer terminates. This is useful if, for example, the user
+ // wishes to visualize the state of the optimization every
+ // iteration.
+ bool update_state_every_iteration;
+
+ // Callbacks that are executed at the end of each iteration of the
+ // Minimizer. An iteration may terminate midway, either due to
+ // numerical failures or because one of the convergence tests has
+ // been satisfied. In this case none of the callbacks are
+ // executed.
+
+ // Callbacks are executed in the order that they are specified in
+ // this vector. By default, parameter blocks are updated only at
+ // the end of the optimization, i.e when the Minimizer
+ // terminates. This behaviour is controlled by
+ // update_state_every_variable. If the user wishes to have access
+ // to the update parameter blocks when his/her callbacks are
+ // executed, then set update_state_every_iteration to true.
+ //
+ // The solver does NOT take ownership of these pointers.
+ vector<IterationCallback*> callbacks;
+ };
+
+ struct CERES_EXPORT Summary {
+ Summary();
+
+ // A brief one line description of the state of the solver after
+ // termination.
+ string BriefReport() const;
+
+ // A full multiline description of the state of the solver after
+ // termination.
+ string FullReport() const;
+
+ bool IsSolutionUsable() const;
+
+ // Minimizer summary -------------------------------------------------
+ TerminationType termination_type;
+
+ // Reason why the solver terminated.
+ string message;
+
+ // Cost of the problem (value of the objective function) before
+ // the optimization.
+ double initial_cost;
+
+ // Cost of the problem (value of the objective function) after the
+ // optimization.
+ double final_cost;
+
+ // IterationSummary for each minimizer iteration in order.
+ vector<IterationSummary> iterations;
+
+ // Sum total of all time spent inside Ceres when Solve is called.
+ double total_time_in_seconds;
+
+ // Time (in seconds) spent evaluating the residual vector.
+ double cost_evaluation_time_in_seconds;
+
+ // Time (in seconds) spent evaluating the jacobian matrix.
+ double gradient_evaluation_time_in_seconds;
+
+ // Number of parameters in the probem.
+ int num_parameters;
+
+ // Dimension of the tangent space of the problem.
+ int num_local_parameters;
+
+ // Type of line search direction used.
+ LineSearchDirectionType line_search_direction_type;
+
+ // Type of the line search algorithm used.
+ LineSearchType line_search_type;
+
+ // When performing line search, the degree of the polynomial used
+ // to approximate the objective function.
+ LineSearchInterpolationType line_search_interpolation_type;
+
+ // If the line search direction is NONLINEAR_CONJUGATE_GRADIENT,
+ // then this indicates the particular variant of non-linear
+ // conjugate gradient used.
+ NonlinearConjugateGradientType nonlinear_conjugate_gradient_type;
+
+ // If the type of the line search direction is LBFGS, then this
+ // indicates the rank of the Hessian approximation.
+ int max_lbfgs_rank;
+ };
+
+ // Once a least squares problem has been built, this function takes
+ // the problem and optimizes it based on the values of the options
+ // parameters. Upon return, a detailed summary of the work performed
+ // by the preprocessor, the non-linear minmizer and the linear
+ // solver are reported in the summary object.
+ virtual void Solve(const GradientProblemSolver::Options& options,
+ const GradientProblem& problem,
+ double* parameters,
+ GradientProblemSolver::Summary* summary);
+};
+
+// Helper function which avoids going through the interface.
+CERES_EXPORT void Solve(const GradientProblemSolver::Options& options,
+ const GradientProblem& problem,
+ double* parameters,
+ GradientProblemSolver::Summary* summary);
+
+} // namespace ceres
+
+#include "ceres/internal/reenable_warnings.h"
+
+#endif // CERES_PUBLIC_GRADIENT_PROBLEM_SOLVER_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/disable_warnings.h b/extern/libmv/third_party/ceres/include/ceres/internal/disable_warnings.h
new file mode 100644
index 00000000000..78924de1346
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/disable_warnings.h
@@ -0,0 +1,44 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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.
+//
+// This file has the sole purpose to silence warnings when including Ceres.
+
+// This is not your usual header guard. The macro CERES_WARNINGS_DISABLED
+// shows up again in reenable_warnings.h.
+#ifndef CERES_WARNINGS_DISABLED
+#define CERES_WARNINGS_DISABLED
+
+#ifdef _MSC_VER
+#pragma warning( push )
+// Disable the warning C4251 which is trigerred by stl classes in
+// Ceres' public interface. To quote MSDN: "C4251 can be ignored "
+// "if you are deriving from a type in the Standard C++ Library"
+#pragma warning( disable : 4251 )
+#endif
+
+#endif // CERES_WARNINGS_DISABLED
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/numeric_diff.h b/extern/libmv/third_party/ceres/include/ceres/internal/numeric_diff.h
index 5048348564a..3b264b45af3 100644
--- a/extern/libmv/third_party/ceres/include/ceres/internal/numeric_diff.h
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/numeric_diff.h
@@ -103,14 +103,17 @@ struct NumericDiff {
typedef Matrix<double, kNumResiduals, 1> ResidualVector;
typedef Matrix<double, kParameterBlockSize, 1> ParameterVector;
+
+ // The convoluted reasoning for choosing the Row/Column major
+ // ordering of the matrix is an artifact of the restrictions in
+ // Eigen that prevent it from creating RowMajor matrices with a
+ // single column. In these cases, we ask for a ColMajor matrix.
typedef Matrix<double,
kNumResiduals,
kParameterBlockSize,
- (kParameterBlockSize == 1 &&
- kNumResiduals > 1) ? ColMajor : RowMajor>
+ (kParameterBlockSize == 1) ? ColMajor : RowMajor>
JacobianMatrix;
-
Map<JacobianMatrix> parameter_jacobian(jacobian,
NUM_RESIDUALS,
kParameterBlockSize);
diff --git a/extern/libmv/third_party/ceres/include/ceres/internal/reenable_warnings.h b/extern/libmv/third_party/ceres/include/ceres/internal/reenable_warnings.h
new file mode 100644
index 00000000000..1f477d8d2ac
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/internal/reenable_warnings.h
@@ -0,0 +1,38 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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.
+//
+
+// This is not your usual header guard. See disable_warnings.h
+#ifdef CERES_WARNINGS_DISABLED
+#undef CERES_WARNINGS_DISABLED
+
+#ifdef _MSC_VER
+#pragma warning( pop )
+#endif
+
+#endif // CERES_WARNINGS_DISABLED
diff --git a/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h b/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h
index 5eca392da36..237ada6e0c9 100644
--- a/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h
+++ b/extern/libmv/third_party/ceres/include/ceres/iteration_callback.h
@@ -36,6 +36,7 @@
#define CERES_PUBLIC_ITERATION_CALLBACK_H_
#include "ceres/types.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -219,4 +220,6 @@ class CERES_EXPORT IterationCallback {
} // namespace ceres
+#include "ceres/internal/reenable_warnings.h"
+
#endif // CERES_PUBLIC_ITERATION_CALLBACK_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/jet.h b/extern/libmv/third_party/ceres/include/ceres/jet.h
index 81f96c70f73..74ce1e9dd53 100644
--- a/extern/libmv/third_party/ceres/include/ceres/jet.h
+++ b/extern/libmv/third_party/ceres/include/ceres/jet.h
@@ -159,6 +159,7 @@
#include <cmath>
#include <iosfwd>
#include <iostream> // NOLINT
+#include <limits>
#include <string>
#include "Eigen/Core"
@@ -197,10 +198,8 @@ struct Jet {
// to be passed in without being fully evaluated until
// they are assigned to v
template<typename Derived>
- Jet(const T& value, const Eigen::DenseBase<Derived> &vIn)
- : a(value),
- v(vIn)
- {
+ EIGEN_STRONG_INLINE Jet(const T& a, const Eigen::DenseBase<Derived> &v)
+ : a(a), v(v) {
}
// Compound operators
@@ -649,7 +648,9 @@ struct NumTraits<ceres::Jet<T, N> > {
return ceres::Jet<T, N>(1e-12);
}
- static inline Real epsilon() { return Real(std::numeric_limits<T>::epsilon()); }
+ static inline Real epsilon() {
+ return Real(std::numeric_limits<T>::epsilon());
+ }
enum {
IsComplex = 0,
diff --git a/extern/libmv/third_party/ceres/include/ceres/local_parameterization.h b/extern/libmv/third_party/ceres/include/ceres/local_parameterization.h
index ecac5ba3ce0..656c4d46662 100644
--- a/extern/libmv/third_party/ceres/include/ceres/local_parameterization.h
+++ b/extern/libmv/third_party/ceres/include/ceres/local_parameterization.h
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2014 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -34,6 +34,7 @@
#include <vector>
#include "ceres/internal/port.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -109,7 +110,7 @@ namespace ceres {
// Jacobian which is needed to compute the Jacobian of f w.r.t delta.
class CERES_EXPORT LocalParameterization {
public:
- virtual ~LocalParameterization() {}
+ virtual ~LocalParameterization();
// Generalization of the addition operation,
//
@@ -121,8 +122,23 @@ class CERES_EXPORT LocalParameterization {
double* x_plus_delta) const = 0;
// The jacobian of Plus(x, delta) w.r.t delta at delta = 0.
+ //
+ // jacobian is a row-major GlobalSize() x LocalSize() matrix.
virtual bool ComputeJacobian(const double* x, double* jacobian) const = 0;
+ // local_matrix = global_matrix * jacobian
+ //
+ // global_matrix is a num_rows x GlobalSize row major matrix.
+ // local_matrix is a num_rows x LocalSize row major matrix.
+ // jacobian(x) is the matrix returned by ComputeJacobian at x.
+ //
+ // This is only used by GradientProblem. For most normal uses, it is
+ // okay to use the default implementation.
+ virtual bool MultiplyByJacobian(const double* x,
+ const int num_rows,
+ const double* global_matrix,
+ double* local_matrix) const;
+
// Size of x.
virtual int GlobalSize() const = 0;
@@ -142,6 +158,10 @@ class CERES_EXPORT IdentityParameterization : public LocalParameterization {
double* x_plus_delta) const;
virtual bool ComputeJacobian(const double* x,
double* jacobian) const;
+ virtual bool MultiplyByJacobian(const double* x,
+ const int num_cols,
+ const double* global_matrix,
+ double* local_matrix) const;
virtual int GlobalSize() const { return size_; }
virtual int LocalSize() const { return size_; }
@@ -160,6 +180,10 @@ class CERES_EXPORT SubsetParameterization : public LocalParameterization {
double* x_plus_delta) const;
virtual bool ComputeJacobian(const double* x,
double* jacobian) const;
+ virtual bool MultiplyByJacobian(const double* x,
+ const int num_cols,
+ const double* global_matrix,
+ double* local_matrix) const;
virtual int GlobalSize() const {
return static_cast<int>(constancy_mask_.size());
}
@@ -188,4 +212,6 @@ class CERES_EXPORT QuaternionParameterization : public LocalParameterization {
} // namespace ceres
+#include "ceres/internal/reenable_warnings.h"
+
#endif // CERES_PUBLIC_LOCAL_PARAMETERIZATION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/loss_function.h b/extern/libmv/third_party/ceres/include/ceres/loss_function.h
index 5b6bf68e700..2c585009990 100644
--- a/extern/libmv/third_party/ceres/include/ceres/loss_function.h
+++ b/extern/libmv/third_party/ceres/include/ceres/loss_function.h
@@ -75,10 +75,11 @@
#ifndef CERES_PUBLIC_LOSS_FUNCTION_H_
#define CERES_PUBLIC_LOSS_FUNCTION_H_
+#include "glog/logging.h"
#include "ceres/internal/macros.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
-#include "glog/logging.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -395,4 +396,6 @@ class CERES_EXPORT LossFunctionWrapper : public LossFunction {
} // namespace ceres
+#include "ceres/internal/disable_warnings.h"
+
#endif // CERES_PUBLIC_LOSS_FUNCTION_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/normal_prior.h b/extern/libmv/third_party/ceres/include/ceres/normal_prior.h
index 530e65253bb..df665054530 100644
--- a/extern/libmv/third_party/ceres/include/ceres/normal_prior.h
+++ b/extern/libmv/third_party/ceres/include/ceres/normal_prior.h
@@ -36,6 +36,7 @@
#include "ceres/cost_function.h"
#include "ceres/internal/eigen.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -72,4 +73,6 @@ class CERES_EXPORT NormalPrior: public CostFunction {
} // namespace ceres
+#include "ceres/internal/reenable_warnings.h"
+
#endif // CERES_PUBLIC_NORMAL_PRIOR_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/numeric_diff_functor.h b/extern/libmv/third_party/ceres/include/ceres/numeric_diff_functor.h
deleted file mode 100644
index a29eb97fa6e..00000000000
--- a/extern/libmv/third_party/ceres/include/ceres/numeric_diff_functor.h
+++ /dev/null
@@ -1,351 +0,0 @@
-// 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)
-//
-// A wrapper class that takes a variadic functor evaluating a
-// function, numerically differentiates it and makes it available as a
-// templated functor so that it can be easily used as part of Ceres'
-// automatic differentiation framework.
-//
-// For example:
-//
-// For example, let us assume that
-//
-// struct IntrinsicProjection
-// IntrinsicProjection(const double* observations);
-// bool operator()(const double* calibration,
-// const double* point,
-// double* residuals);
-// };
-//
-// is a functor that implements the projection of a point in its local
-// coordinate system onto its image plane and subtracts it from the
-// observed point projection.
-//
-// Now we would like to compose the action of this functor with the
-// action of camera extrinsics, i.e., rotation and translation, which
-// is given by the following templated function
-//
-// template<typename T>
-// void RotateAndTranslatePoint(const T* rotation,
-// const T* translation,
-// const T* point,
-// T* result);
-//
-// To compose the extrinsics and intrinsics, we can construct a
-// CameraProjection functor as follows.
-//
-// struct CameraProjection {
-// typedef NumericDiffFunctor<IntrinsicProjection, CENTRAL, 2, 5, 3>
-// IntrinsicProjectionFunctor;
-//
-// CameraProjection(double* observation) {
-// intrinsic_projection_.reset(
-// new IntrinsicProjectionFunctor(observation)) {
-// }
-//
-// template <typename T>
-// bool operator()(const T* rotation,
-// const T* translation,
-// const T* intrinsics,
-// const T* point,
-// T* residuals) const {
-// T transformed_point[3];
-// RotateAndTranslatePoint(rotation, translation, point, transformed_point);
-// return (*intrinsic_projection_)(intrinsics, transformed_point, residual);
-// }
-//
-// private:
-// scoped_ptr<IntrinsicProjectionFunctor> intrinsic_projection_;
-// };
-//
-// Here, we made the choice of using CENTRAL differences to compute
-// the jacobian of IntrinsicProjection.
-//
-// Now, we are ready to construct an automatically differentiated cost
-// function as
-//
-// CostFunction* cost_function =
-// new AutoDiffCostFunction<CameraProjection, 2, 3, 3, 5>(
-// new CameraProjection(observations));
-//
-// cost_function now seamlessly integrates automatic differentiation
-// of RotateAndTranslatePoint with a numerically differentiated
-// version of IntrinsicProjection.
-
-#ifndef CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
-#define CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
-
-#include "ceres/numeric_diff_cost_function.h"
-#include "ceres/types.h"
-#include "ceres/cost_function_to_functor.h"
-
-namespace ceres {
-
-template<typename Functor,
- NumericDiffMethod kMethod = CENTRAL,
- int kNumResiduals = 0,
- int N0 = 0, int N1 = 0 , int N2 = 0, int N3 = 0, int N4 = 0,
- int N5 = 0, int N6 = 0 , int N7 = 0, int N8 = 0, int N9 = 0>
-class NumericDiffFunctor {
- public:
- // relative_step_size controls the step size used by the numeric
- // differentiation process.
- explicit NumericDiffFunctor(double relative_step_size = 1e-6)
- : functor_(
- new NumericDiffCostFunction<Functor,
- kMethod,
- kNumResiduals,
- N0, N1, N2, N3, N4,
- N5, N6, N7, N8, N9>(new Functor,
- TAKE_OWNERSHIP,
- kNumResiduals,
- relative_step_size)) {
- }
-
- NumericDiffFunctor(Functor* functor, double relative_step_size = 1e-6)
- : functor_(new NumericDiffCostFunction<Functor,
- kMethod,
- kNumResiduals,
- N0, N1, N2, N3, N4,
- N5, N6, N7, N8, N9>(
- functor,
- TAKE_OWNERSHIP,
- kNumResiduals,
- relative_step_size)) {
- }
-
- bool operator()(const double* x0, double* residuals) const {
- return functor_(x0, residuals);
- }
-
- bool operator()(const double* x0,
- const double* x1,
- double* residuals) const {
- return functor_(x0, x1, residuals);
- }
-
- bool operator()(const double* x0,
- const double* x1,
- const double* x2,
- double* residuals) const {
- return functor_(x0, x1, x2, residuals);
- }
-
- bool operator()(const double* x0,
- const double* x1,
- const double* x2,
- const double* x3,
- double* residuals) const {
- return functor_(x0, x1, x2, x3, residuals);
- }
-
- bool operator()(const double* x0,
- const double* x1,
- const double* x2,
- const double* x3,
- const double* x4,
- double* residuals) const {
- return functor_(x0, x1, x2, x3, x4, residuals);
- }
-
- bool operator()(const double* x0,
- const double* x1,
- const double* x2,
- const double* x3,
- const double* x4,
- const double* x5,
- double* residuals) const {
- return functor_(x0, x1, x2, x3, x4, x5, residuals);
- }
-
- bool operator()(const double* x0,
- const double* x1,
- const double* x2,
- const double* x3,
- const double* x4,
- const double* x5,
- const double* x6,
- double* residuals) const {
- return functor_(x0, x1, x2, x3, x4, x5, x6, residuals);
- }
-
- bool operator()(const double* x0,
- const double* x1,
- const double* x2,
- const double* x3,
- const double* x4,
- const double* x5,
- const double* x6,
- const double* x7,
- double* residuals) const {
- return functor_(x0, x1, x2, x3, x4, x5, x6, x7, residuals);
- }
-
- bool operator()(const double* x0,
- const double* x1,
- const double* x2,
- const double* x3,
- const double* x4,
- const double* x5,
- const double* x6,
- const double* x7,
- const double* x8,
- double* residuals) const {
- return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, residuals);
- }
-
- bool operator()(const double* x0,
- const double* x1,
- const double* x2,
- const double* x3,
- const double* x4,
- const double* x5,
- const double* x6,
- const double* x7,
- const double* x8,
- const double* x9,
- double* residuals) const {
- return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, residuals);
- }
-
- template <typename T>
- bool operator()(const T* x0, T* residuals) const {
- return functor_(x0, residuals);
- }
-
- template <typename T>
- bool operator()(const T* x0,
- const T* x1,
- T* residuals) const {
- return functor_(x0, x1, residuals);
- }
-
- template <typename T>
- bool operator()(const T* x0,
- const T* x1,
- const T* x2,
- T* residuals) const {
- return functor_(x0, x1, x2, residuals);
- }
-
- template <typename T>
- bool operator()(const T* x0,
- const T* x1,
- const T* x2,
- const T* x3,
- T* residuals) const {
- return functor_(x0, x1, x2, x3, residuals);
- }
-
- template <typename T>
- bool operator()(const T* x0,
- const T* x1,
- const T* x2,
- const T* x3,
- const T* x4,
- T* residuals) const {
- return functor_(x0, x1, x2, x3, x4, residuals);
- }
-
- template <typename T>
- bool operator()(const T* x0,
- const T* x1,
- const T* x2,
- const T* x3,
- const T* x4,
- const T* x5,
- T* residuals) const {
- return functor_(x0, x1, x2, x3, x4, x5, residuals);
- }
-
- template <typename T>
- bool operator()(const T* x0,
- const T* x1,
- const T* x2,
- const T* x3,
- const T* x4,
- const T* x5,
- const T* x6,
- T* residuals) const {
- return functor_(x0, x1, x2, x3, x4, x5, x6, residuals);
- }
-
- template <typename T>
- bool operator()(const T* x0,
- const T* x1,
- const T* x2,
- const T* x3,
- const T* x4,
- const T* x5,
- const T* x6,
- const T* x7,
- T* residuals) const {
- return functor_(x0, x1, x2, x3, x4, x5, x6, x7, residuals);
- }
-
- template <typename T>
- bool operator()(const T* x0,
- const T* x1,
- const T* x2,
- const T* x3,
- const T* x4,
- const T* x5,
- const T* x6,
- const T* x7,
- const T* x8,
- T* residuals) const {
- return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, residuals);
- }
-
- template <typename T>
- bool operator()(const T* x0,
- const T* x1,
- const T* x2,
- const T* x3,
- const T* x4,
- const T* x5,
- const T* x6,
- const T* x7,
- const T* x8,
- const T* x9,
- T* residuals) const {
- return functor_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, residuals);
- }
-
-
- private:
- CostFunctionToFunctor<kNumResiduals,
- N0, N1, N2, N3, N4,
- N5, N6, N7, N8, N9> functor_;
-};
-
-} // namespace ceres
-
-#endif // CERES_PUBLIC_NUMERIC_DIFF_FUNCTOR_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/ordered_groups.h b/extern/libmv/third_party/ceres/include/ceres/ordered_groups.h
index dff859d7b82..c316d712e97 100644
--- a/extern/libmv/third_party/ceres/include/ceres/ordered_groups.h
+++ b/extern/libmv/third_party/ceres/include/ceres/ordered_groups.h
@@ -33,7 +33,9 @@
#include <map>
#include <set>
+#include <vector>
#include "ceres/internal/port.h"
+#include "glog/logging.h"
namespace ceres {
@@ -103,6 +105,20 @@ class OrderedGroups {
return true;
}
+ // Bulk remove elements. The return value indicates the number of
+ // elements successfully removed.
+ int Remove(const vector<T>& elements) {
+ if (NumElements() == 0 || elements.size() == 0) {
+ return 0;
+ }
+
+ int num_removed = 0;
+ for (int i = 0; i < elements.size(); ++i) {
+ num_removed += Remove(elements[i]);
+ }
+ return num_removed;
+ }
+
// Reverse the order of the groups in place.
void Reverse() {
typename map<int, set<T> >::reverse_iterator it =
@@ -156,10 +172,22 @@ class OrderedGroups {
return group_to_elements_.size();
}
+ // The first group with one or more elements. Calling this when
+ // there are no groups with non-zero elements will result in a
+ // crash.
+ int MinNonZeroGroup() const {
+ CHECK_NE(NumGroups(), 0);
+ return group_to_elements_.begin()->first;
+ }
+
const map<int, set<T> >& group_to_elements() const {
return group_to_elements_;
}
+ const map<T, int>& element_to_group() const {
+ return element_to_group_;
+ }
+
private:
map<int, set<T> > group_to_elements_;
map<T, int> element_to_group_;
diff --git a/extern/libmv/third_party/ceres/include/ceres/problem.h b/extern/libmv/third_party/ceres/include/ceres/problem.h
index 5881677a815..f75ede3a5c6 100644
--- a/extern/libmv/third_party/ceres/include/ceres/problem.h
+++ b/extern/libmv/third_party/ceres/include/ceres/problem.h
@@ -39,11 +39,12 @@
#include <set>
#include <vector>
+#include "glog/logging.h"
#include "ceres/internal/macros.h"
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
-#include "glog/logging.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -367,6 +368,15 @@ class CERES_EXPORT Problem {
const ResidualBlockId residual_block,
vector<double*>* parameter_blocks) const;
+ // Get the CostFunction for the given residual block.
+ const CostFunction* GetCostFunctionForResidualBlock(
+ const ResidualBlockId residual_block) const;
+
+ // Get the LossFunction for the given residual block. Returns NULL
+ // if no loss function is associated with this residual block.
+ const LossFunction* GetLossFunctionForResidualBlock(
+ const ResidualBlockId residual_block) const;
+
// Get all the residual blocks that depend on the given parameter block.
//
// If Problem::Options::enable_fast_removal is true, then
@@ -466,4 +476,6 @@ class CERES_EXPORT Problem {
} // namespace ceres
+#include "ceres/internal/reenable_warnings.h"
+
#endif // CERES_PUBLIC_PROBLEM_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/solver.h b/extern/libmv/third_party/ceres/include/ceres/solver.h
index fc70073ec89..a5efa2a3915 100644
--- a/extern/libmv/third_party/ceres/include/ceres/solver.h
+++ b/extern/libmv/third_party/ceres/include/ceres/solver.h
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2014 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -40,6 +40,7 @@
#include "ceres/iteration_callback.h"
#include "ceres/ordered_groups.h"
#include "ceres/types.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -91,7 +92,7 @@ class CERES_EXPORT Solver {
gradient_tolerance = 1e-10;
parameter_tolerance = 1e-8;
-#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
+#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE) && !defined(CERES_ENABLE_LGPL_CODE)
linear_solver_type = DENSE_QR;
#else
linear_solver_type = SPARSE_NORMAL_CHOLESKY;
@@ -100,16 +101,27 @@ class CERES_EXPORT Solver {
preconditioner_type = JACOBI;
visibility_clustering_type = CANONICAL_VIEWS;
dense_linear_algebra_library_type = EIGEN;
+
+ // Choose a default sparse linear algebra library in the order:
+ //
+ // SUITE_SPARSE > CX_SPARSE > EIGEN_SPARSE
+#if !defined(CERES_NO_SUITESPARSE)
sparse_linear_algebra_library_type = SUITE_SPARSE;
-#if defined(CERES_NO_SUITESPARSE) && !defined(CERES_NO_CXSPARSE)
+#else
+ #if !defined(CERES_NO_CXSPARSE)
sparse_linear_algebra_library_type = CX_SPARSE;
+ #else
+ #if defined(CERES_USE_EIGEN_SPARSE)
+ sparse_linear_algebra_library_type = EIGEN_SPARSE;
+ #endif
+ #endif
#endif
-
num_linear_solver_threads = 1;
+ use_explicit_schur_complement = false;
use_postordering = false;
dynamic_sparsity = false;
- min_linear_solver_iterations = 1;
+ min_linear_solver_iterations = 0;
max_linear_solver_iterations = 500;
eta = 1e-1;
jacobi_scaling = true;
@@ -125,6 +137,11 @@ class CERES_EXPORT Solver {
update_state_every_iteration = false;
}
+ // Returns true if the options struct has a valid
+ // configuration. Returns false otherwise, and fills in *error
+ // with a message describing the problem.
+ bool IsValid(string* error) const;
+
// Minimizer options ----------------------------------------
// Ceres supports the two major families of optimization strategies -
@@ -480,6 +497,29 @@ class CERES_EXPORT Solver {
// smaller than the group containing cameras.
shared_ptr<ParameterBlockOrdering> linear_solver_ordering;
+ // Use an explicitly computed Schur complement matrix with
+ // ITERATIVE_SCHUR.
+ //
+ // By default this option is disabled and ITERATIVE_SCHUR
+ // evaluates evaluates matrix-vector products between the Schur
+ // complement and a vector implicitly by exploiting the algebraic
+ // expression for the Schur complement.
+ //
+ // The cost of this evaluation scales with the number of non-zeros
+ // in the Jacobian.
+ //
+ // For small to medium sized problems there is a sweet spot where
+ // computing the Schur complement is cheap enough that it is much
+ // more efficient to explicitly compute it and use it for evaluating
+ // the matrix-vector products.
+ //
+ // Enabling this option tells ITERATIVE_SCHUR to use an explicitly
+ // computed Schur complement.
+ //
+ // NOTE: This option can only be used with the SCHUR_JACOBI
+ // preconditioner.
+ bool use_explicit_schur_complement;
+
// Sparse Cholesky factorization algorithms use a fill-reducing
// ordering to permute the columns of the Jacobian matrix. There
// are two ways of doing this.
@@ -707,10 +747,6 @@ class CERES_EXPORT Solver {
//
// The solver does NOT take ownership of these pointers.
vector<IterationCallback*> callbacks;
-
- // If non-empty, a summary of the execution of the solver is
- // recorded to this file.
- string solver_log;
};
struct CERES_EXPORT Summary {
@@ -898,9 +934,15 @@ class CERES_EXPORT Solver {
// parameter blocks.
vector<int> inner_iteration_ordering_used;
- // Type of preconditioner used for solving the trust region
- // step. Only meaningful when an iterative linear solver is used.
- PreconditionerType preconditioner_type;
+ // Type of the preconditioner requested by the user.
+ PreconditionerType preconditioner_type_given;
+
+ // Type of the preconditioner actually used. This may be different
+ // from linear_solver_type_given if Ceres determines that the
+ // problem structure is not compatible with the linear solver
+ // requested or if the linear solver requested by the user is not
+ // available.
+ PreconditionerType preconditioner_type_used;
// Type of clustering algorithm used for visibility based
// preconditioning. Only meaningful when the preconditioner_type
@@ -957,4 +999,6 @@ CERES_EXPORT void Solve(const Solver::Options& options,
} // namespace ceres
+#include "ceres/internal/reenable_warnings.h"
+
#endif // CERES_PUBLIC_SOLVER_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/types.h b/extern/libmv/third_party/ceres/include/ceres/types.h
index ff31d4530db..a07c8933e64 100644
--- a/extern/libmv/third_party/ceres/include/ceres/types.h
+++ b/extern/libmv/third_party/ceres/include/ceres/types.h
@@ -40,6 +40,7 @@
#include <string>
#include "ceres/internal/port.h"
+#include "ceres/internal/disable_warnings.h"
namespace ceres {
@@ -149,8 +150,14 @@ enum SparseLinearAlgebraLibraryType {
// minimum degree ordering.
SUITE_SPARSE,
- // A lightweight replacment for SuiteSparse.
- CX_SPARSE
+ // A lightweight replacment for SuiteSparse, which does not require
+ // a LAPACK/BLAS implementation. Consequently, its performance is
+ // also a bit lower than SuiteSparse.
+ CX_SPARSE,
+
+ // Eigen's sparse linear algebra routines. In particular Ceres uses
+ // the Simplicial LDLT routines.
+ EIGEN_SPARSE
};
enum DenseLinearAlgebraLibraryType {
@@ -246,7 +253,7 @@ enum LineSearchDirectionType {
// details see Numerical Optimization by Nocedal & Wright.
enum NonlinearConjugateGradientType {
FLETCHER_REEVES,
- POLAK_RIBIRERE,
+ POLAK_RIBIERE,
HESTENES_STIEFEL,
};
@@ -398,8 +405,8 @@ enum LineSearchInterpolationType {
enum CovarianceAlgorithmType {
DENSE_SVD,
- SPARSE_CHOLESKY,
- SPARSE_QR
+ SUITE_SPARSE_QR,
+ EIGEN_SPARSE_QR
};
CERES_EXPORT const char* LinearSolverTypeToString(
@@ -475,4 +482,6 @@ CERES_EXPORT bool IsDenseLinearAlgebraLibraryTypeAvailable(
} // namespace ceres
+#include "ceres/internal/reenable_warnings.h"
+
#endif // CERES_PUBLIC_TYPES_H_
diff --git a/extern/libmv/third_party/ceres/include/ceres/version.h b/extern/libmv/third_party/ceres/include/ceres/version.h
new file mode 100644
index 00000000000..370b08af73e
--- /dev/null
+++ b/extern/libmv/third_party/ceres/include/ceres/version.h
@@ -0,0 +1,49 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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: mierle@gmail.com (Keir Mierle)
+
+#ifndef CERES_PUBLIC_VERSION_H_
+#define CERES_PUBLIC_VERSION_H_
+
+#define CERES_VERSION_MAJOR 1
+#define CERES_VERSION_MINOR 10
+#define CERES_VERSION_REVISION 0
+#define CERES_VERSION_ABI 1
+
+// Classic CPP stringifcation; the extra level of indirection allows the
+// preprocessor to expand the macro before being converted to a string.
+#define CERES_TO_STRING_HELPER(x) #x
+#define CERES_TO_STRING(x) CERES_TO_STRING_HELPER(x)
+
+// The Ceres version as a string; for example "1.9.0".
+#define CERES_VERSION_STRING CERES_TO_STRING(CERES_VERSION_MAJOR) "." \
+ CERES_TO_STRING(CERES_VERSION_MINOR) "." \
+ CERES_TO_STRING(CERES_VERSION_REVISION)
+
+#endif // CERES_PUBLIC_VERSION_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/CMakeLists.txt b/extern/libmv/third_party/ceres/internal/ceres/CMakeLists.txt
deleted file mode 100644
index 1dd40900031..00000000000
--- a/extern/libmv/third_party/ceres/internal/ceres/CMakeLists.txt
+++ /dev/null
@@ -1,287 +0,0 @@
-# Ceres Solver - A fast non-linear least squares minimizer
-# Copyright 2010, 2011, 2012 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: keir@google.com (Keir Mierle)
-
-SET(CERES_INTERNAL_SRC
- array_utils.cc
- blas.cc
- block_evaluate_preparer.cc
- block_jacobi_preconditioner.cc
- block_jacobian_writer.cc
- block_random_access_dense_matrix.cc
- block_random_access_diagonal_matrix.cc
- block_random_access_matrix.cc
- block_random_access_sparse_matrix.cc
- block_sparse_matrix.cc
- block_structure.cc
- c_api.cc
- canonical_views_clustering.cc
- cgnr_solver.cc
- compressed_col_sparse_matrix_utils.cc
- compressed_row_jacobian_writer.cc
- compressed_row_sparse_matrix.cc
- conditioned_cost_function.cc
- conjugate_gradients_solver.cc
- coordinate_descent_minimizer.cc
- corrector.cc
- covariance.cc
- covariance_impl.cc
- cxsparse.cc
- dense_normal_cholesky_solver.cc
- dense_qr_solver.cc
- dense_sparse_matrix.cc
- detect_structure.cc
- dogleg_strategy.cc
- dynamic_compressed_row_jacobian_writer.cc
- dynamic_compressed_row_sparse_matrix.cc
- evaluator.cc
- file.cc
- gradient_checking_cost_function.cc
- implicit_schur_complement.cc
- incomplete_lq_factorization.cc
- iterative_schur_complement_solver.cc
- levenberg_marquardt_strategy.cc
- lapack.cc
- line_search.cc
- line_search_direction.cc
- line_search_minimizer.cc
- linear_least_squares_problems.cc
- linear_operator.cc
- linear_solver.cc
- local_parameterization.cc
- loss_function.cc
- low_rank_inverse_hessian.cc
- minimizer.cc
- normal_prior.cc
- parameter_block_ordering.cc
- partitioned_matrix_view.cc
- polynomial.cc
- preconditioner.cc
- problem.cc
- problem_impl.cc
- program.cc
- residual_block.cc
- residual_block_utils.cc
- schur_complement_solver.cc
- schur_eliminator.cc
- schur_jacobi_preconditioner.cc
- scratch_evaluate_preparer.cc
- single_linkage_clustering.cc
- solver.cc
- solver_impl.cc
- sparse_matrix.cc
- sparse_normal_cholesky_solver.cc
- split.cc
- stringprintf.cc
- suitesparse.cc
- triplet_sparse_matrix.cc
- trust_region_minimizer.cc
- trust_region_strategy.cc
- types.cc
- visibility.cc
- visibility_based_preconditioner.cc
- wall_time.cc
-)
-
-# Heuristic for determining LIB_SUFFIX. FHS recommends that 64-bit systems
-# install native libraries to lib64 rather than lib. Most distros seem to
-# follow this convention with a couple notable exceptions (Debian-based and
-# Arch-based distros) which we try to detect here.
-IF (CMAKE_SYSTEM_NAME MATCHES "Linux" AND
- NOT DEFINED LIB_SUFFIX AND
- NOT CMAKE_CROSSCOMPILING AND
- CMAKE_SIZEOF_VOID_P EQUAL "8" AND
- NOT EXISTS "/etc/debian_version" AND
- NOT EXISTS "/etc/arch-release")
- SET(LIB_SUFFIX "64")
-ENDIF ()
-
-# Also depend on the header files so that they appear in IDEs.
-FILE(GLOB CERES_INTERNAL_HDRS *.h)
-
-# Include the specialized schur solvers.
-IF (SCHUR_SPECIALIZATIONS)
- FILE(GLOB CERES_INTERNAL_SCHUR_FILES generated/*.cc)
-ELSE (SCHUR_SPECIALIZATIONS)
- # Only the fully dynamic solver. The build is much faster this way.
- FILE(GLOB CERES_INTERNAL_SCHUR_FILES generated/*_d_d_d.cc)
-ENDIF (SCHUR_SPECIALIZATIONS)
-
-# Primarily for Android, but optionally for others, use the minimal internal
-# Glog implementation.
-IF (MINIGLOG)
- ADD_LIBRARY(miniglog STATIC miniglog/glog/logging.cc)
- INSTALL(TARGETS miniglog
- EXPORT CeresExport
- RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib${LIB_SUFFIX}
- ARCHIVE DESTINATION lib${LIB_SUFFIX})
-ENDIF (MINIGLOG)
-
-SET(CERES_LIBRARY_PUBLIC_DEPENDENCIES ${GLOG_LIBRARIES})
-
-IF (SUITESPARSE AND SUITESPARSE_FOUND)
- LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${SUITESPARSE_LIBRARIES})
-ENDIF (SUITESPARSE AND SUITESPARSE_FOUND)
-
-IF (CXSPARSE AND CXSPARSE_FOUND)
- LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${CXSPARSE_LIBRARIES})
-ENDIF (CXSPARSE AND CXSPARSE_FOUND)
-
-IF (BLAS_FOUND AND LAPACK_FOUND)
- LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${LAPACK_LIBRARIES})
- LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${BLAS_LIBRARIES})
-ENDIF (BLAS_FOUND AND LAPACK_FOUND)
-
-IF (OPENMP_FOUND)
- IF (NOT MSVC)
- LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES gomp)
- LIST(APPEND CERES_LIBRARY_PRIVATE_DEPENDENCIES ${CMAKE_THREAD_LIBS_INIT})
- ENDIF (NOT MSVC)
-ENDIF (OPENMP_FOUND)
-
-SET(CERES_LIBRARY_SOURCE
- ${CERES_INTERNAL_SRC}
- ${CERES_INTERNAL_HDRS}
- ${CERES_INTERNAL_SCHUR_FILES})
-
-ADD_LIBRARY(ceres ${CERES_LIBRARY_SOURCE})
-SET_TARGET_PROPERTIES(ceres PROPERTIES
- VERSION ${CERES_VERSION}
- SOVERSION ${CERES_VERSION_MAJOR}
-)
-
-IF (BUILD_SHARED_LIBS)
- # When building a shared library, mark all external libraries as
- # PRIVATE so they don't show up as a dependency.
- TARGET_LINK_LIBRARIES(ceres
- LINK_PUBLIC ${CERES_LIBRARY_PUBLIC_DEPENDENCIES}
- LINK_PRIVATE ${CERES_LIBRARY_PRIVATE_DEPENDENCIES})
-ELSE (BUILD_SHARED_LIBS)
- # When building a static library, all external libraries are
- # PUBLIC(default) since the user needs to link to them.
- # They will be listed in CeresTargets.cmake.
- SET(CERES_LIBRARY_DEPENDENCIES
- ${CERES_LIBRARY_PUBLIC_DEPENDENCIES}
- ${CERES_LIBRARY_PRIVATE_DEPENDENCIES})
- TARGET_LINK_LIBRARIES(ceres ${CERES_LIBRARY_DEPENDENCIES})
-ENDIF (BUILD_SHARED_LIBS)
-
-INSTALL(TARGETS ceres
- EXPORT CeresExport
- RUNTIME DESTINATION bin
- LIBRARY DESTINATION lib${LIB_SUFFIX}
- ARCHIVE DESTINATION lib${LIB_SUFFIX})
-
-IF (BUILD_TESTING AND GFLAGS)
- ADD_LIBRARY(gtest gmock_gtest_all.cc gmock_main.cc)
- ADD_LIBRARY(test_util
- evaluator_test_utils.cc
- numeric_diff_test_utils.cc
- test_util.cc)
-
- TARGET_LINK_LIBRARIES(gtest ${GFLAGS_LIBRARIES} ${GLOG_LIBRARIES})
- TARGET_LINK_LIBRARIES(test_util ceres gtest ${GLOG_LIBRARIES})
-
- MACRO (CERES_TEST NAME)
- ADD_EXECUTABLE(${NAME}_test ${NAME}_test.cc)
- TARGET_LINK_LIBRARIES(${NAME}_test test_util ceres gtest)
- ADD_TEST(NAME ${NAME}_test
- COMMAND ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${NAME}_test
- --test_srcdir
- ${CMAKE_SOURCE_DIR}/data)
- ENDMACRO (CERES_TEST)
-
- CERES_TEST(array_utils)
- CERES_TEST(autodiff)
- CERES_TEST(autodiff_cost_function)
- CERES_TEST(autodiff_local_parameterization)
- CERES_TEST(block_random_access_dense_matrix)
- CERES_TEST(block_random_access_diagonal_matrix)
- CERES_TEST(block_random_access_sparse_matrix)
- CERES_TEST(block_sparse_matrix)
- CERES_TEST(c_api)
- CERES_TEST(canonical_views_clustering)
- CERES_TEST(compressed_row_sparse_matrix)
- CERES_TEST(conditioned_cost_function)
- CERES_TEST(corrector)
- CERES_TEST(cost_function_to_functor)
- CERES_TEST(covariance)
- CERES_TEST(dense_sparse_matrix)
- CERES_TEST(dynamic_autodiff_cost_function)
- CERES_TEST(dynamic_compressed_row_sparse_matrix)
- CERES_TEST(dynamic_numeric_diff_cost_function)
- CERES_TEST(evaluator)
- CERES_TEST(gradient_checker)
- CERES_TEST(gradient_checking_cost_function)
- CERES_TEST(graph)
- CERES_TEST(graph_algorithms)
- CERES_TEST(implicit_schur_complement)
- CERES_TEST(incomplete_lq_factorization)
- CERES_TEST(iterative_schur_complement_solver)
- CERES_TEST(jet)
- CERES_TEST(levenberg_marquardt_strategy)
- CERES_TEST(dogleg_strategy)
- CERES_TEST(local_parameterization)
- CERES_TEST(loss_function)
- CERES_TEST(minimizer)
- CERES_TEST(normal_prior)
- CERES_TEST(numeric_diff_cost_function)
- CERES_TEST(numeric_diff_functor)
- CERES_TEST(ordered_groups)
- CERES_TEST(parameter_block)
- CERES_TEST(parameter_block_ordering)
- CERES_TEST(partitioned_matrix_view)
- CERES_TEST(polynomial)
- CERES_TEST(problem)
- CERES_TEST(residual_block)
- CERES_TEST(residual_block_utils)
- CERES_TEST(rotation)
- CERES_TEST(schur_complement_solver)
- CERES_TEST(schur_eliminator)
- CERES_TEST(single_linkage_clustering)
- CERES_TEST(small_blas)
- CERES_TEST(solver_impl)
-
- # TODO(sameeragarwal): This test should ultimately be made
- # independent of SuiteSparse.
- IF (SUITESPARSE AND SUITESPARSE_FOUND)
- CERES_TEST(compressed_col_sparse_matrix_utils)
- ENDIF (SUITESPARSE AND SUITESPARSE_FOUND)
-
- CERES_TEST(symmetric_linear_solver)
- CERES_TEST(triplet_sparse_matrix)
- CERES_TEST(trust_region_minimizer)
- CERES_TEST(unsymmetric_linear_solver)
- CERES_TEST(visibility)
- CERES_TEST(visibility_based_preconditioner)
-
- # Put the large end to end test last.
- CERES_TEST(system)
-ENDIF (BUILD_TESTING AND GFLAGS)
diff --git a/extern/libmv/third_party/ceres/internal/ceres/array_utils.cc b/extern/libmv/third_party/ceres/internal/ceres/array_utils.cc
index 3eea042d511..205ddaf27c9 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/array_utils.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/array_utils.cc
@@ -30,10 +30,11 @@
#include "ceres/array_utils.h"
+#include <algorithm>
#include <cmath>
#include <cstddef>
#include <string>
-
+#include <vector>
#include "ceres/fpclassify.h"
#include "ceres/stringprintf.h"
@@ -94,5 +95,19 @@ void AppendArrayToString(const int size, const double* x, string* result) {
}
}
+void MapValuesToContiguousRange(const int size, int* array) {
+ std::vector<int> unique_values(array, array + size);
+ std::sort(unique_values.begin(), unique_values.end());
+ unique_values.erase(std::unique(unique_values.begin(),
+ unique_values.end()),
+ unique_values.end());
+
+ for (int i = 0; i < size; ++i) {
+ array[i] = std::lower_bound(unique_values.begin(),
+ unique_values.end(),
+ array[i]) - unique_values.begin();
+ }
+}
+
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/array_utils.h b/extern/libmv/third_party/ceres/internal/ceres/array_utils.h
index 34fda6fd475..7f56947066b 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/array_utils.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/array_utils.h
@@ -67,6 +67,21 @@ void AppendArrayToString(const int size, const double* x, string* result);
extern const double kImpossibleValue;
+// This routine takes an array of integer values, sorts and uniques
+// them and then maps each value in the array to its position in the
+// sorted+uniqued array. By doing this, if there are are k unique
+// values in the array, each value is replaced by an integer in the
+// range [0, k-1], while preserving their relative order.
+//
+// For example
+//
+// [1 0 3 5 0 1 5]
+//
+// gets mapped to
+//
+// [1 0 2 3 0 1 3]
+void MapValuesToContiguousRange(int size, int* array);
+
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc
index 19b749bfc39..7f79a4f993d 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.cc
@@ -30,9 +30,9 @@
#include "ceres/block_jacobi_preconditioner.h"
-#include "Eigen/Cholesky"
#include "ceres/block_sparse_matrix.h"
#include "ceres/block_structure.h"
+#include "ceres/block_random_access_diagonal_matrix.h"
#include "ceres/casts.h"
#include "ceres/integral_types.h"
#include "ceres/internal/eigen.h"
@@ -41,27 +41,14 @@ namespace ceres {
namespace internal {
BlockJacobiPreconditioner::BlockJacobiPreconditioner(
- const BlockSparseMatrix& A)
- : num_rows_(A.num_rows()),
- block_structure_(*A.block_structure()) {
- // Calculate the amount of storage needed.
- int storage_needed = 0;
- for (int c = 0; c < block_structure_.cols.size(); ++c) {
- int size = block_structure_.cols[c].size;
- storage_needed += size * size;
+ const BlockSparseMatrix& A) {
+ const CompressedRowBlockStructure* bs = A.block_structure();
+ vector<int> blocks(bs->cols.size());
+ for (int i = 0; i < blocks.size(); ++i) {
+ blocks[i] = bs->cols[i].size;
}
- // Size the offsets and storage.
- blocks_.resize(block_structure_.cols.size());
- block_storage_.resize(storage_needed);
-
- // Put pointers to the storage in the offsets.
- double* block_cursor = &block_storage_[0];
- for (int c = 0; c < block_structure_.cols.size(); ++c) {
- int size = block_structure_.cols[c].size;
- blocks_[c] = block_cursor;
- block_cursor += size * size;
- }
+ m_.reset(new BlockRandomAccessDiagonalMatrix(blocks));
}
BlockJacobiPreconditioner::~BlockJacobiPreconditioner() {}
@@ -69,70 +56,50 @@ BlockJacobiPreconditioner::~BlockJacobiPreconditioner() {}
bool BlockJacobiPreconditioner::UpdateImpl(const BlockSparseMatrix& A,
const double* D) {
const CompressedRowBlockStructure* bs = A.block_structure();
-
- // Compute the diagonal blocks by block inner products.
- std::fill(block_storage_.begin(), block_storage_.end(), 0.0);
const double* values = A.values();
- for (int r = 0; r < bs->rows.size(); ++r) {
- const int row_block_size = bs->rows[r].block.size;
- const vector<Cell>& cells = bs->rows[r].cells;
- for (int c = 0; c < cells.size(); ++c) {
- const int col_block_size = bs->cols[cells[c].block_id].size;
- ConstMatrixRef m(values + cells[c].position,
+ m_->SetZero();
+ for (int i = 0; i < bs->rows.size(); ++i) {
+ const int row_block_size = bs->rows[i].block.size;
+ const vector<Cell>& cells = bs->rows[i].cells;
+ for (int j = 0; j < cells.size(); ++j) {
+ const int block_id = cells[j].block_id;
+ const int col_block_size = bs->cols[block_id].size;
+
+ int r, c, row_stride, col_stride;
+ CellInfo* cell_info = m_->GetCell(block_id, block_id,
+ &r, &c,
+ &row_stride, &col_stride);
+ MatrixRef m(cell_info->values, row_stride, col_stride);
+ ConstMatrixRef b(values + cells[j].position,
row_block_size,
col_block_size);
-
- MatrixRef(blocks_[cells[c].block_id],
- col_block_size,
- col_block_size).noalias() += m.transpose() * m;
-
- // TODO(keir): Figure out when the below expression is actually faster
- // than doing the full rank update. The issue is that for smaller sizes,
- // the rankUpdate() function is slower than the full product done above.
- //
- // On the typical bundling problems, the above product is ~5% faster.
- //
- // MatrixRef(blocks_[cells[c].block_id],
- // col_block_size,
- // col_block_size)
- // .selfadjointView<Eigen::Upper>()
- // .rankUpdate(m);
- //
+ m.block(r, c, col_block_size, col_block_size) += b.transpose() * b;
}
}
- // Add the diagonal and invert each block.
- for (int c = 0; c < bs->cols.size(); ++c) {
- const int size = block_structure_.cols[c].size;
- const int position = block_structure_.cols[c].position;
- MatrixRef block(blocks_[c], size, size);
-
- if (D != NULL) {
- block.diagonal() +=
- ConstVectorRef(D + position, size).array().square().matrix();
+ if (D != NULL) {
+ // Add the diagonal.
+ int position = 0;
+ for (int i = 0; i < bs->cols.size(); ++i) {
+ const int block_size = bs->cols[i].size;
+ int r, c, row_stride, col_stride;
+ CellInfo* cell_info = m_->GetCell(i, i,
+ &r, &c,
+ &row_stride, &col_stride);
+ MatrixRef m(cell_info->values, row_stride, col_stride);
+ m.block(r, c, block_size, block_size).diagonal() +=
+ ConstVectorRef(D + position, block_size).array().square().matrix();
+ position += block_size;
}
-
- block = block.selfadjointView<Eigen::Upper>()
- .llt()
- .solve(Matrix::Identity(size, size));
}
+
+ m_->Invert();
return true;
}
void BlockJacobiPreconditioner::RightMultiply(const double* x,
double* y) const {
- for (int c = 0; c < block_structure_.cols.size(); ++c) {
- const int size = block_structure_.cols[c].size;
- const int position = block_structure_.cols[c].position;
- ConstMatrixRef D(blocks_[c], size, size);
- ConstVectorRef x_block(x + position, size);
- VectorRef y_block(y + position, size);
- y_block += D * x_block;
- }
-}
-
-void BlockJacobiPreconditioner::LeftMultiply(const double* x, double* y) const {
- RightMultiply(x, y);
+ m_->RightMultiply(x, y);
}
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h
index 3505a01248b..e23e0e2d24c 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_jacobi_preconditioner.h
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2012 Google Inc. All rights reserved.
+// Copyright 2014 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,8 @@
#define CERES_INTERNAL_BLOCK_JACOBI_PRECONDITIONER_H_
#include <vector>
+#include "ceres/block_random_access_diagonal_matrix.h"
+#include "ceres/internal/scoped_ptr.h"
#include "ceres/preconditioner.h"
namespace ceres {
@@ -39,7 +41,6 @@ namespace internal {
class BlockSparseMatrix;
struct CompressedRowBlockStructure;
-class LinearOperator;
// A block Jacobi preconditioner. This is intended for use with
// conjugate gradients, or other iterative symmetric solvers. To use
@@ -59,19 +60,14 @@ class BlockJacobiPreconditioner : public BlockSparseMatrixPreconditioner {
// Preconditioner interface
virtual void RightMultiply(const double* x, double* y) const;
- virtual void LeftMultiply(const double* x, double* y) const;
- virtual int num_rows() const { return num_rows_; }
- virtual int num_cols() const { return num_rows_; }
+ virtual int num_rows() const { return m_->num_rows(); }
+ virtual int num_cols() const { return m_->num_rows(); }
+ const BlockRandomAccessDiagonalMatrix& matrix() const { return *m_; }
private:
virtual bool UpdateImpl(const BlockSparseMatrix& A, const double* D);
- std::vector<double*> blocks_;
- std::vector<double> block_storage_;
- int num_rows_;
-
- // The block structure of the matrix this preconditioner is for (e.g. J).
- const CompressedRowBlockStructure& block_structure_;
+ scoped_ptr<BlockRandomAccessDiagonalMatrix> m_;
};
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_diagonal_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_diagonal_matrix.cc
index d8bf4ef0cb5..b7ff33184cb 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_diagonal_matrix.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_diagonal_matrix.cc
@@ -34,16 +34,19 @@
#include <set>
#include <utility>
#include <vector>
+#include "Eigen/Dense"
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
+#include "ceres/stl_util.h"
#include "ceres/triplet_sparse_matrix.h"
#include "ceres/types.h"
-#include "ceres/stl_util.h"
#include "glog/logging.h"
namespace ceres {
namespace internal {
+// TODO(sameeragarwal): Drop the dependence on TripletSparseMatrix.
+
BlockRandomAccessDiagonalMatrix::BlockRandomAccessDiagonalMatrix(
const vector<int>& blocks)
: blocks_(blocks) {
@@ -51,9 +54,9 @@ BlockRandomAccessDiagonalMatrix::BlockRandomAccessDiagonalMatrix(
// rows/columns.
int num_cols = 0;
int num_nonzeros = 0;
- vector<int> col_layout;
+ vector<int> block_positions;
for (int i = 0; i < blocks_.size(); ++i) {
- col_layout.push_back(num_cols);
+ block_positions.push_back(num_cols);
num_cols += blocks_[i];
num_nonzeros += blocks_[i] * blocks_[i];
}
@@ -72,7 +75,7 @@ BlockRandomAccessDiagonalMatrix::BlockRandomAccessDiagonalMatrix(
for (int i = 0; i < blocks_.size(); ++i) {
const int block_size = blocks_[i];
layout_.push_back(new CellInfo(values + pos));
- const int block_begin = col_layout[i];
+ const int block_begin = block_positions[i];
for (int r = 0; r < block_size; ++r) {
for (int c = 0; c < block_size; ++c, ++pos) {
rows[pos] = block_begin + r;
@@ -116,5 +119,34 @@ void BlockRandomAccessDiagonalMatrix::SetZero() {
}
}
+void BlockRandomAccessDiagonalMatrix::Invert() {
+ double* values = tsm_->mutable_values();
+ for (int i = 0; i < blocks_.size(); ++i) {
+ const int block_size = blocks_[i];
+ MatrixRef block(values, block_size, block_size);
+ block =
+ block
+ .selfadjointView<Eigen::Upper>()
+ .llt()
+ .solve(Matrix::Identity(block_size, block_size));
+ values += block_size * block_size;
+ }
+}
+
+void BlockRandomAccessDiagonalMatrix::RightMultiply(const double* x,
+ double* y) const {
+ CHECK_NOTNULL(x);
+ CHECK_NOTNULL(y);
+ const double* values = tsm_->values();
+ for (int i = 0; i < blocks_.size(); ++i) {
+ const int block_size = blocks_[i];
+ ConstMatrixRef block(values, block_size, block_size);
+ VectorRef(y, block_size).noalias() += block * ConstVectorRef(x, block_size);
+ x += block_size;
+ y += block_size;
+ values += block_size * block_size;
+ }
+}
+
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_diagonal_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_diagonal_matrix.h
index 6b3cff2338f..ea9967817db 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_diagonal_matrix.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_diagonal_matrix.h
@@ -52,7 +52,7 @@ namespace internal {
class BlockRandomAccessDiagonalMatrix : public BlockRandomAccessMatrix {
public:
// blocks is an array of block sizes.
- BlockRandomAccessDiagonalMatrix(const vector<int>& blocks);
+ explicit BlockRandomAccessDiagonalMatrix(const vector<int>& blocks);
// The destructor is not thread safe. It assumes that no one is
// modifying any cells when the matrix is being destroyed.
@@ -70,11 +70,16 @@ class BlockRandomAccessDiagonalMatrix : public BlockRandomAccessMatrix {
// locked.
virtual void SetZero();
+ // Invert the matrix assuming that each block is positive definite.
+ void Invert();
+
+ // y += S * x
+ void RightMultiply(const double* x, double* y) const;
+
// Since the matrix is square, num_rows() == num_cols().
virtual int num_rows() const { return tsm_->num_rows(); }
virtual int num_cols() const { return tsm_->num_cols(); }
- // Access to the underlying matrix object.
const TripletSparseMatrix* matrix() const { return tsm_.get(); }
TripletSparseMatrix* mutable_matrix() { return tsm_.get(); }
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc
index f789436364a..c43a9b78feb 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.cc
@@ -54,9 +54,9 @@ BlockRandomAccessSparseMatrix::BlockRandomAccessSparseMatrix(
// Build the row/column layout vector and count the number of scalar
// rows/columns.
int num_cols = 0;
- vector<int> col_layout;
+ block_positions_.reserve(blocks_.size());
for (int i = 0; i < blocks_.size(); ++i) {
- col_layout.push_back(num_cols);
+ block_positions_.push_back(num_cols);
num_cols += blocks_[i];
}
@@ -88,6 +88,8 @@ BlockRandomAccessSparseMatrix::BlockRandomAccessSparseMatrix(
++it) {
const int row_block_size = blocks_[it->first];
const int col_block_size = blocks_[it->second];
+ cell_values_.push_back(make_pair(make_pair(it->first, it->second),
+ values + pos));
layout_[IntPairToLong(it->first, it->second)] =
new CellInfo(values + pos);
pos += row_block_size * col_block_size;
@@ -105,8 +107,8 @@ BlockRandomAccessSparseMatrix::BlockRandomAccessSparseMatrix(
layout_[IntPairToLong(row_block_id, col_block_id)]->values - values;
for (int r = 0; r < row_block_size; ++r) {
for (int c = 0; c < col_block_size; ++c, ++pos) {
- rows[pos] = col_layout[row_block_id] + r;
- cols[pos] = col_layout[col_block_id] + c;
+ rows[pos] = block_positions_[row_block_id] + r;
+ cols[pos] = block_positions_[col_block_id] + c;
values[pos] = 1.0;
DCHECK_LT(rows[pos], tsm_->num_rows());
DCHECK_LT(cols[pos], tsm_->num_rows());
@@ -154,5 +156,36 @@ void BlockRandomAccessSparseMatrix::SetZero() {
}
}
+void BlockRandomAccessSparseMatrix::SymmetricRightMultiply(const double* x,
+ double* y) const {
+ vector< pair<pair<int, int>, double*> >::const_iterator it =
+ cell_values_.begin();
+ for (; it != cell_values_.end(); ++it) {
+ const int row = it->first.first;
+ const int row_block_size = blocks_[row];
+ const int row_block_pos = block_positions_[row];
+
+ const int col = it->first.second;
+ const int col_block_size = blocks_[col];
+ const int col_block_pos = block_positions_[col];
+
+ MatrixVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
+ it->second, row_block_size, col_block_size,
+ x + col_block_pos,
+ y + row_block_pos);
+
+ // Since the matrix is symmetric, but only the upper triangular
+ // part is stored, if the block being accessed is not a diagonal
+ // block, then use the same block to do the corresponding lower
+ // triangular multiply also.
+ if (row != col) {
+ MatrixTransposeVectorMultiply<Eigen::Dynamic, Eigen::Dynamic, 1>(
+ it->second, row_block_size, col_block_size,
+ x + row_block_pos,
+ y + col_block_pos);
+ }
+ }
+}
+
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.h b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.h
index 27b10296d6c..51b5d20cfe0 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/block_random_access_sparse_matrix.h
@@ -43,6 +43,7 @@
#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
+#include "ceres/small_blas.h"
namespace ceres {
namespace internal {
@@ -75,6 +76,12 @@ class BlockRandomAccessSparseMatrix : public BlockRandomAccessMatrix {
// locked.
virtual void SetZero();
+ // Assume that the matrix is symmetric and only one half of the
+ // matrix is stored.
+ //
+ // y += S * x
+ void SymmetricRightMultiply(const double* x, double* y) const;
+
// Since the matrix is square, num_rows() == num_cols().
virtual int num_rows() const { return tsm_->num_rows(); }
virtual int num_cols() const { return tsm_->num_cols(); }
@@ -84,19 +91,30 @@ class BlockRandomAccessSparseMatrix : public BlockRandomAccessMatrix {
TripletSparseMatrix* mutable_matrix() { return tsm_.get(); }
private:
- int64 IntPairToLong(int a, int b) {
- return a * kMaxRowBlocks + b;
+ int64 IntPairToLong(int row, int col) const {
+ return row * kMaxRowBlocks + col;
+ }
+
+ void LongToIntPair(int64 index, int* row, int* col) const {
+ *row = index / kMaxRowBlocks;
+ *col = index % kMaxRowBlocks;
}
const int64 kMaxRowBlocks;
+
// row/column block sizes.
const vector<int> blocks_;
+ vector<int> block_positions_;
// A mapping from <row_block_id, col_block_id> to the position in
// the values array of tsm_ where the block is stored.
typedef HashMap<long int, CellInfo* > LayoutType;
LayoutType layout_;
+ // In order traversal of contents of the matrix. This allows us to
+ // implement a matrix-vector which is 20% faster than using the
+ // iterator in the Layout object instead.
+ vector<pair<pair<int, int>, double*> > cell_values_;
// The underlying matrix object which actually stores the cells.
scoped_ptr<TripletSparseMatrix> tsm_;
diff --git a/extern/libmv/third_party/ceres/internal/ceres/callbacks.cc b/extern/libmv/third_party/ceres/internal/ceres/callbacks.cc
new file mode 100644
index 00000000000..7d5ce2548e4
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/callbacks.cc
@@ -0,0 +1,109 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#include <iostream> // NO LINT
+#include "ceres/callbacks.h"
+#include "ceres/program.h"
+#include "ceres/stringprintf.h"
+#include "glog/logging.h"
+
+namespace ceres {
+namespace internal {
+
+StateUpdatingCallback::StateUpdatingCallback(Program* program,
+ double* parameters)
+ : program_(program), parameters_(parameters) {}
+
+StateUpdatingCallback::~StateUpdatingCallback() {}
+
+CallbackReturnType StateUpdatingCallback::operator()(
+ const IterationSummary& summary) {
+ if (summary.step_is_successful) {
+ program_->StateVectorToParameterBlocks(parameters_);
+ program_->CopyParameterBlockStateToUserState();
+ }
+ return SOLVER_CONTINUE;
+}
+
+LoggingCallback::LoggingCallback(const MinimizerType minimizer_type,
+ const bool log_to_stdout)
+ : minimizer_type(minimizer_type),
+ log_to_stdout_(log_to_stdout) {}
+
+LoggingCallback::~LoggingCallback() {}
+
+CallbackReturnType LoggingCallback::operator()(
+ const IterationSummary& summary) {
+ string output;
+ if (minimizer_type == LINE_SEARCH) {
+ const char* kReportRowFormat =
+ "% 4d: f:% 8e d:% 3.2e g:% 3.2e h:% 3.2e "
+ "s:% 3.2e e:% 3d it:% 3.2e tt:% 3.2e";
+ output = StringPrintf(kReportRowFormat,
+ summary.iteration,
+ summary.cost,
+ summary.cost_change,
+ summary.gradient_max_norm,
+ summary.step_norm,
+ summary.step_size,
+ summary.line_search_function_evaluations,
+ summary.iteration_time_in_seconds,
+ summary.cumulative_time_in_seconds);
+ } else if (minimizer_type == TRUST_REGION) {
+ if (summary.iteration == 0) {
+ output = "iter cost cost_change |gradient| |step| tr_ratio tr_radius ls_iter iter_time total_time\n";
+ }
+ const char* kReportRowFormat =
+ "% 4d % 8e % 3.2e % 3.2e % 3.2e % 3.2e % 3.2e % 4d % 3.2e % 3.2e";
+ output += StringPrintf(kReportRowFormat,
+ summary.iteration,
+ summary.cost,
+ summary.cost_change,
+ summary.gradient_max_norm,
+ summary.step_norm,
+ summary.relative_decrease,
+ summary.trust_region_radius,
+ summary.linear_solver_iterations,
+ summary.iteration_time_in_seconds,
+ summary.cumulative_time_in_seconds);
+ } else {
+ LOG(FATAL) << "Unknown minimizer type.";
+ }
+
+ if (log_to_stdout_) {
+ cout << output << endl;
+ } else {
+ VLOG(1) << output;
+ }
+ return SOLVER_CONTINUE;
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/callbacks.h b/extern/libmv/third_party/ceres/internal/ceres/callbacks.h
new file mode 100644
index 00000000000..93704dfd6d1
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/callbacks.h
@@ -0,0 +1,71 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#ifndef CERES_INTERNAL_CALLBACKS_H_
+#define CERES_INTERNAL_CALLBACKS_H_
+
+#include <string>
+#include "ceres/iteration_callback.h"
+#include "ceres/internal/port.h"
+
+namespace ceres {
+namespace internal {
+
+class Program;
+
+// Callback for updating the externally visible state of parameter
+// blocks.
+class StateUpdatingCallback : public IterationCallback {
+ public:
+ StateUpdatingCallback(Program* program, double* parameters);
+ virtual ~StateUpdatingCallback();
+ virtual CallbackReturnType operator()(const IterationSummary& summary);
+ private:
+ Program* program_;
+ double* parameters_;
+};
+
+// Callback for logging the state of the minimizer to STDERR or
+// STDOUT depending on the user's preferences and logging level.
+class LoggingCallback : public IterationCallback {
+ public:
+ LoggingCallback(MinimizerType minimizer_type, bool log_to_stdout);
+ virtual ~LoggingCallback();
+ virtual CallbackReturnType operator()(const IterationSummary& summary);
+
+ private:
+ const MinimizerType minimizer_type;
+ const bool log_to_stdout_;
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_CALLBACKS_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.cc b/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.cc
index 2f032e6580a..9bbab4b2377 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.cc
@@ -61,7 +61,7 @@ class CanonicalViewsClustering {
// vertices may not be assigned to any cluster. In this case they
// are assigned to a cluster with id = kInvalidClusterId.
void ComputeClustering(const CanonicalViewsClusteringOptions& options,
- const Graph<int>& graph,
+ const WeightedGraph<int>& graph,
vector<int>* centers,
IntMap* membership);
@@ -74,7 +74,7 @@ class CanonicalViewsClustering {
IntMap* membership) const;
CanonicalViewsClusteringOptions options_;
- const Graph<int>* graph_;
+ const WeightedGraph<int>* graph_;
// Maps a view to its representative canonical view (its cluster
// center).
IntMap view_to_canonical_view_;
@@ -85,7 +85,7 @@ class CanonicalViewsClustering {
void ComputeCanonicalViewsClustering(
const CanonicalViewsClusteringOptions& options,
- const Graph<int>& graph,
+ const WeightedGraph<int>& graph,
vector<int>* centers,
IntMap* membership) {
time_t start_time = time(NULL);
@@ -98,7 +98,7 @@ void ComputeCanonicalViewsClustering(
// Implementation of CanonicalViewsClustering
void CanonicalViewsClustering::ComputeClustering(
const CanonicalViewsClusteringOptions& options,
- const Graph<int>& graph,
+ const WeightedGraph<int>& graph,
vector<int>* centers,
IntMap* membership) {
options_ = options;
@@ -150,7 +150,7 @@ void CanonicalViewsClustering::FindValidViews(
for (IntSet::const_iterator view = views.begin();
view != views.end();
++view) {
- if (graph_->VertexWeight(*view) != Graph<int>::InvalidWeight()) {
+ if (graph_->VertexWeight(*view) != WeightedGraph<int>::InvalidWeight()) {
valid_views->insert(*view);
}
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h b/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h
index 1b4c4ee059f..d3fa5725831 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/canonical_views_clustering.h
@@ -101,7 +101,7 @@ struct CanonicalViewsClusteringOptions;
// cluster. In this case they are assigned to a cluster with id = -1;
void ComputeCanonicalViewsClustering(
const CanonicalViewsClusteringOptions& options,
- const Graph<int>& graph,
+ const WeightedGraph<int>& graph,
vector<int>* centers,
HashMap<int, int>* membership);
diff --git a/extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.cc
index 524cb8ad988..3071a0918e4 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/conjugate_gradients_solver.cc
@@ -101,7 +101,7 @@ LinearSolver::Summary ConjugateGradientsSolver::Solve(
A->RightMultiply(x, tmp.data());
r = bref - tmp;
double norm_r = r.norm();
- if (norm_r <= tol_r) {
+ if (options_.min_num_iterations == 0 && norm_r <= tol_r) {
summary.termination_type = LINEAR_SOLVER_SUCCESS;
summary.message =
StringPrintf("Convergence. |r| = %e <= %e.", norm_r, tol_r);
@@ -113,9 +113,8 @@ LinearSolver::Summary ConjugateGradientsSolver::Solve(
// Initial value of the quadratic model Q = x'Ax - 2 * b'x.
double Q0 = -1.0 * xref.dot(bref + r);
- for (summary.num_iterations = 1;
- summary.num_iterations < options_.max_num_iterations;
- ++summary.num_iterations) {
+ for (summary.num_iterations = 1;; ++summary.num_iterations) {
+
// Apply preconditioner
if (per_solve_options.preconditioner != NULL) {
z.setZero();
@@ -207,7 +206,8 @@ LinearSolver::Summary ConjugateGradientsSolver::Solve(
// 124(1-2), 45-59, 2000.
//
const double zeta = summary.num_iterations * (Q1 - Q0) / Q1;
- if (zeta < per_solve_options.q_tolerance) {
+ if (zeta < per_solve_options.q_tolerance &&
+ summary.num_iterations >= options_.min_num_iterations) {
summary.termination_type = LINEAR_SOLVER_SUCCESS;
summary.message =
StringPrintf("Convergence: zeta = %e < %e",
@@ -219,12 +219,17 @@ LinearSolver::Summary ConjugateGradientsSolver::Solve(
// Residual based termination.
norm_r = r. norm();
- if (norm_r <= tol_r) {
+ if (norm_r <= tol_r &&
+ summary.num_iterations >= options_.min_num_iterations) {
summary.termination_type = LINEAR_SOLVER_SUCCESS;
summary.message =
StringPrintf("Convergence. |r| = %e <= %e.", norm_r, tol_r);
break;
}
+
+ if (summary.num_iterations >= options_.max_num_iterations) {
+ break;
+ }
}
return summary;
diff --git a/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.cc b/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.cc
index bfe93c49826..1d55458bb69 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.cc
@@ -40,15 +40,15 @@
#include "ceres/evaluator.h"
#include "ceres/linear_solver.h"
#include "ceres/minimizer.h"
-#include "ceres/ordered_groups.h"
#include "ceres/parameter_block.h"
+#include "ceres/parameter_block_ordering.h"
#include "ceres/problem_impl.h"
#include "ceres/program.h"
#include "ceres/residual_block.h"
#include "ceres/solver.h"
-#include "ceres/solver_impl.h"
#include "ceres/trust_region_minimizer.h"
#include "ceres/trust_region_strategy.h"
+#include "ceres/parameter_block_ordering.h"
namespace ceres {
namespace internal {
@@ -210,28 +210,54 @@ void CoordinateDescentMinimizer::Solve(Program* program,
summary->final_cost = 0.0;
string error;
- scoped_ptr<Evaluator> evaluator(
- Evaluator::Create(evaluator_options_, program, &error));
- CHECK_NOTNULL(evaluator.get());
-
- scoped_ptr<SparseMatrix> jacobian(evaluator->CreateJacobian());
- CHECK_NOTNULL(jacobian.get());
+ Minimizer::Options minimizer_options;
+ minimizer_options.evaluator.reset(
+ CHECK_NOTNULL(Evaluator::Create(evaluator_options_, program, &error)));
+ minimizer_options.jacobian.reset(
+ CHECK_NOTNULL(minimizer_options.evaluator->CreateJacobian()));
TrustRegionStrategy::Options trs_options;
trs_options.linear_solver = linear_solver;
-
- scoped_ptr<TrustRegionStrategy>trust_region_strategy(
+ minimizer_options.trust_region_strategy.reset(
CHECK_NOTNULL(TrustRegionStrategy::Create(trs_options)));
-
- Minimizer::Options minimizer_options;
- minimizer_options.evaluator = evaluator.get();
- minimizer_options.jacobian = jacobian.get();
- minimizer_options.trust_region_strategy = trust_region_strategy.get();
minimizer_options.is_silent = true;
TrustRegionMinimizer minimizer;
minimizer.Minimize(minimizer_options, parameter, summary);
}
+bool CoordinateDescentMinimizer::IsOrderingValid(
+ const Program& program,
+ const ParameterBlockOrdering& ordering,
+ string* message) {
+ const map<int, set<double*> >& group_to_elements =
+ ordering.group_to_elements();
+
+ // Verify that each group is an independent set
+ map<int, set<double*> >::const_iterator it = group_to_elements.begin();
+ for ( ; it != group_to_elements.end(); ++it) {
+ if (!program.IsParameterBlockSetIndependent(it->second)) {
+ *message =
+ StringPrintf("The user-provided "
+ "parameter_blocks_for_inner_iterations does not "
+ "form an independent set. Group Id: %d", it->first);
+ return false;
+ }
+ }
+ return true;
+}
+
+// Find a recursive decomposition of the Hessian matrix as a set
+// of independent sets of decreasing size and invert it. This
+// seems to work better in practice, i.e., Cameras before
+// points.
+ParameterBlockOrdering* CoordinateDescentMinimizer::CreateOrdering(
+ const Program& program) {
+ scoped_ptr<ParameterBlockOrdering> ordering(new ParameterBlockOrdering);
+ ComputeRecursiveIndependentSetOrdering(program, ordering.get());
+ ordering->Reverse();
+ return ordering.release();
+}
+
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.h b/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.h
index 424acda94ae..c1f8ffcd02a 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/coordinate_descent_minimizer.h
@@ -37,12 +37,14 @@
#include "ceres/evaluator.h"
#include "ceres/minimizer.h"
#include "ceres/problem_impl.h"
-#include "ceres/program.h"
#include "ceres/solver.h"
namespace ceres {
namespace internal {
+class Program;
+class LinearSolver;
+
// Given a Program, and a ParameterBlockOrdering which partitions
// (non-exhaustively) the Hessian matrix into independent sets,
// perform coordinate descent on the parameter blocks in the
@@ -66,6 +68,17 @@ class CoordinateDescentMinimizer : public Minimizer {
double* parameters,
Solver::Summary* summary);
+ // Verify that each group in the ordering forms an independent set.
+ static bool IsOrderingValid(const Program& program,
+ const ParameterBlockOrdering& ordering,
+ string* message);
+
+ // Find a recursive decomposition of the Hessian matrix as a set
+ // of independent sets of decreasing size and invert it. This
+ // seems to work better in practice, i.e., Cameras before
+ // points.
+ static ParameterBlockOrdering* CreateOrdering(const Program& program);
+
private:
void Solve(Program* program,
LinearSolver* linear_solver,
diff --git a/extern/libmv/third_party/ceres/internal/ceres/covariance_impl.cc b/extern/libmv/third_party/ceres/internal/ceres/covariance_impl.cc
index 75c80bf5687..cfbfb445343 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/covariance_impl.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/covariance_impl.cc
@@ -38,6 +38,25 @@
#include <cstdlib>
#include <utility>
#include <vector>
+#include "Eigen/SparseCore"
+
+// Suppress unused local variable warning from Eigen Ordering.h #included by
+// SparseQR in Eigen 3.2.0. This was fixed in Eigen 3.2.1, but 3.2.0 is still
+// widely used (Ubuntu 14.04), and Ceres won't compile otherwise due to -Werror.
+#if defined(_MSC_VER)
+#pragma warning( push )
+#pragma warning( disable : 4189 )
+#else
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wunused-but-set-variable"
+#endif
+#include "Eigen/SparseQR"
+#if defined(_MSC_VER)
+#pragma warning( pop )
+#else
+#pragma GCC diagnostic pop
+#endif
+
#include "Eigen/SVD"
#include "ceres/compressed_col_sparse_matrix_utils.h"
#include "ceres/compressed_row_sparse_matrix.h"
@@ -53,40 +72,6 @@
namespace ceres {
namespace internal {
-namespace {
-
-// Per thread storage for SuiteSparse.
-#ifndef CERES_NO_SUITESPARSE
-
-struct PerThreadContext {
- explicit PerThreadContext(int num_rows)
- : solution(NULL),
- solution_set(NULL),
- y_workspace(NULL),
- e_workspace(NULL),
- rhs(NULL) {
- rhs = ss.CreateDenseVector(NULL, num_rows, num_rows);
- }
-
- ~PerThreadContext() {
- ss.Free(solution);
- ss.Free(solution_set);
- ss.Free(y_workspace);
- ss.Free(e_workspace);
- ss.Free(rhs);
- }
-
- cholmod_dense* solution;
- cholmod_sparse* solution_set;
- cholmod_dense* y_workspace;
- cholmod_dense* e_workspace;
- cholmod_dense* rhs;
- SuiteSparse ss;
-};
-
-#endif
-
-} // namespace
typedef vector<pair<const double*, const double*> > CovarianceBlocks;
@@ -94,8 +79,17 @@ CovarianceImpl::CovarianceImpl(const Covariance::Options& options)
: options_(options),
is_computed_(false),
is_valid_(false) {
- evaluate_options_.num_threads = options.num_threads;
- evaluate_options_.apply_loss_function = options.apply_loss_function;
+#ifndef CERES_USE_OPENMP
+ if (options_.num_threads > 1) {
+ LOG(WARNING)
+ << "OpenMP support is not compiled into this binary; "
+ << "only options.num_threads = 1 is supported. Switching "
+ << "to single threaded mode.";
+ options_.num_threads = 1;
+ }
+#endif
+ evaluate_options_.num_threads = options_.num_threads;
+ evaluate_options_.apply_loss_function = options_.apply_loss_function;
}
CovarianceImpl::~CovarianceImpl() {
@@ -396,11 +390,15 @@ bool CovarianceImpl::ComputeCovarianceValues() {
case DENSE_SVD:
return ComputeCovarianceValuesUsingDenseSVD();
#ifndef CERES_NO_SUITESPARSE
- case SPARSE_CHOLESKY:
- return ComputeCovarianceValuesUsingSparseCholesky();
- case SPARSE_QR:
- return ComputeCovarianceValuesUsingSparseQR();
+ case SUITE_SPARSE_QR:
+ return ComputeCovarianceValuesUsingSuiteSparseQR();
+#else
+ LOG(ERROR) << "SuiteSparse is required to use the "
+ << "SUITE_SPARSE_QR algorithm.";
+ return false;
#endif
+ case EIGEN_SPARSE_QR:
+ return ComputeCovarianceValuesUsingEigenSparseQR();
default:
LOG(ERROR) << "Unsupported covariance estimation algorithm type: "
<< CovarianceAlgorithmTypeToString(options_.algorithm_type);
@@ -409,197 +407,7 @@ bool CovarianceImpl::ComputeCovarianceValues() {
return false;
}
-bool CovarianceImpl::ComputeCovarianceValuesUsingSparseCholesky() {
- EventLogger event_logger(
- "CovarianceImpl::ComputeCovarianceValuesUsingSparseCholesky");
-#ifndef CERES_NO_SUITESPARSE
- if (covariance_matrix_.get() == NULL) {
- // Nothing to do, all zeros covariance matrix.
- return true;
- }
-
- SuiteSparse ss;
-
- CRSMatrix jacobian;
- problem_->Evaluate(evaluate_options_, NULL, NULL, NULL, &jacobian);
-
- event_logger.AddEvent("Evaluate");
- // m is a transposed view of the Jacobian.
- cholmod_sparse cholmod_jacobian_view;
- cholmod_jacobian_view.nrow = jacobian.num_cols;
- cholmod_jacobian_view.ncol = jacobian.num_rows;
- cholmod_jacobian_view.nzmax = jacobian.values.size();
- cholmod_jacobian_view.nz = NULL;
- cholmod_jacobian_view.p = reinterpret_cast<void*>(&jacobian.rows[0]);
- cholmod_jacobian_view.i = reinterpret_cast<void*>(&jacobian.cols[0]);
- cholmod_jacobian_view.x = reinterpret_cast<void*>(&jacobian.values[0]);
- cholmod_jacobian_view.z = NULL;
- cholmod_jacobian_view.stype = 0; // Matrix is not symmetric.
- cholmod_jacobian_view.itype = CHOLMOD_INT;
- cholmod_jacobian_view.xtype = CHOLMOD_REAL;
- cholmod_jacobian_view.dtype = CHOLMOD_DOUBLE;
- cholmod_jacobian_view.sorted = 1;
- cholmod_jacobian_view.packed = 1;
-
- string message;
- cholmod_factor* factor = ss.AnalyzeCholesky(&cholmod_jacobian_view, &message);
- event_logger.AddEvent("Symbolic Factorization");
- if (factor == NULL) {
- LOG(ERROR) << "Covariance estimation failed. "
- << "CHOLMOD symbolic cholesky factorization returned with: "
- << message;
- return false;
- }
-
- LinearSolverTerminationType termination_type =
- ss.Cholesky(&cholmod_jacobian_view, factor, &message);
- event_logger.AddEvent("Numeric Factorization");
- if (termination_type != LINEAR_SOLVER_SUCCESS) {
- LOG(ERROR) << "Covariance estimation failed. "
- << "CHOLMOD numeric cholesky factorization returned with: "
- << message;
- ss.Free(factor);
- return false;
- }
-
- const double reciprocal_condition_number =
- cholmod_rcond(factor, ss.mutable_cc());
-
- if (reciprocal_condition_number <
- options_.min_reciprocal_condition_number) {
- LOG(ERROR) << "Cholesky factorization of J'J is not reliable. "
- << "Reciprocal condition number: "
- << reciprocal_condition_number << " "
- << "min_reciprocal_condition_number: "
- << options_.min_reciprocal_condition_number;
- ss.Free(factor);
- return false;
- }
-
- const int num_rows = covariance_matrix_->num_rows();
- const int* rows = covariance_matrix_->rows();
- const int* cols = covariance_matrix_->cols();
- double* values = covariance_matrix_->mutable_values();
-
- // The following loop exploits the fact that the i^th column of A^{-1}
- // is given by the solution to the linear system
- //
- // A x = e_i
- //
- // where e_i is a vector with e(i) = 1 and all other entries zero.
- //
- // Since the covariance matrix is symmetric, the i^th row and column
- // are equal.
- //
- // The ifdef separates two different version of SuiteSparse. Newer
- // versions of SuiteSparse have the cholmod_solve2 function which
- // re-uses memory across calls.
-#if (SUITESPARSE_VERSION < 4002)
- cholmod_dense* rhs = ss.CreateDenseVector(NULL, num_rows, num_rows);
- double* rhs_x = reinterpret_cast<double*>(rhs->x);
-
- for (int r = 0; r < num_rows; ++r) {
- int row_begin = rows[r];
- int row_end = rows[r + 1];
- if (row_end == row_begin) {
- continue;
- }
-
- rhs_x[r] = 1.0;
- cholmod_dense* solution = ss.Solve(factor, rhs, &message);
- double* solution_x = reinterpret_cast<double*>(solution->x);
- for (int idx = row_begin; idx < row_end; ++idx) {
- const int c = cols[idx];
- values[idx] = solution_x[c];
- }
- ss.Free(solution);
- rhs_x[r] = 0.0;
- }
-
- ss.Free(rhs);
-#else // SUITESPARSE_VERSION < 4002
-
- const int num_threads = options_.num_threads;
- vector<PerThreadContext*> contexts(num_threads);
- for (int i = 0; i < num_threads; ++i) {
- contexts[i] = new PerThreadContext(num_rows);
- }
-
- // The first call to cholmod_solve2 is not thread safe, since it
- // changes the factorization from supernodal to simplicial etc.
- {
- PerThreadContext* context = contexts[0];
- double* context_rhs_x = reinterpret_cast<double*>(context->rhs->x);
- context_rhs_x[0] = 1.0;
- cholmod_solve2(CHOLMOD_A,
- factor,
- context->rhs,
- NULL,
- &context->solution,
- &context->solution_set,
- &context->y_workspace,
- &context->e_workspace,
- context->ss.mutable_cc());
- context_rhs_x[0] = 0.0;
- }
-
-#pragma omp parallel for num_threads(num_threads) schedule(dynamic)
- for (int r = 0; r < num_rows; ++r) {
- int row_begin = rows[r];
- int row_end = rows[r + 1];
- if (row_end == row_begin) {
- continue;
- }
-
-# ifdef CERES_USE_OPENMP
- int thread_id = omp_get_thread_num();
-# else
- int thread_id = 0;
-# endif
-
- PerThreadContext* context = contexts[thread_id];
- double* context_rhs_x = reinterpret_cast<double*>(context->rhs->x);
- context_rhs_x[r] = 1.0;
-
- // TODO(sameeragarwal) There should be a more efficient way
- // involving the use of Bset but I am unable to make it work right
- // now.
- cholmod_solve2(CHOLMOD_A,
- factor,
- context->rhs,
- NULL,
- &context->solution,
- &context->solution_set,
- &context->y_workspace,
- &context->e_workspace,
- context->ss.mutable_cc());
-
- double* solution_x = reinterpret_cast<double*>(context->solution->x);
- for (int idx = row_begin; idx < row_end; ++idx) {
- const int c = cols[idx];
- values[idx] = solution_x[c];
- }
- context_rhs_x[r] = 0.0;
- }
-
- for (int i = 0; i < num_threads; ++i) {
- delete contexts[i];
- }
-
-#endif // SUITESPARSE_VERSION < 4002
-
- ss.Free(factor);
- event_logger.AddEvent("Inversion");
- return true;
-
-#else // CERES_NO_SUITESPARSE
-
- return false;
-
-#endif // CERES_NO_SUITESPARSE
-};
-
-bool CovarianceImpl::ComputeCovarianceValuesUsingSparseQR() {
+bool CovarianceImpl::ComputeCovarianceValuesUsingSuiteSparseQR() {
EventLogger event_logger(
"CovarianceImpl::ComputeCovarianceValuesUsingSparseQR");
@@ -851,7 +659,102 @@ bool CovarianceImpl::ComputeCovarianceValuesUsingDenseSVD() {
}
event_logger.AddEvent("CopyToCovarianceMatrix");
return true;
-};
+}
+
+bool CovarianceImpl::ComputeCovarianceValuesUsingEigenSparseQR() {
+ EventLogger event_logger(
+ "CovarianceImpl::ComputeCovarianceValuesUsingEigenSparseQR");
+ if (covariance_matrix_.get() == NULL) {
+ // Nothing to do, all zeros covariance matrix.
+ return true;
+ }
+
+ CRSMatrix jacobian;
+ problem_->Evaluate(evaluate_options_, NULL, NULL, NULL, &jacobian);
+ event_logger.AddEvent("Evaluate");
+
+ typedef Eigen::SparseMatrix<double, Eigen::ColMajor> EigenSparseMatrix;
+
+ // Convert the matrix to column major order as required by SparseQR.
+ EigenSparseMatrix sparse_jacobian =
+ Eigen::MappedSparseMatrix<double, Eigen::RowMajor>(
+ jacobian.num_rows, jacobian.num_cols,
+ static_cast<int>(jacobian.values.size()),
+ jacobian.rows.data(), jacobian.cols.data(), jacobian.values.data());
+ event_logger.AddEvent("ConvertToSparseMatrix");
+
+ Eigen::SparseQR<EigenSparseMatrix, Eigen::COLAMDOrdering<int> >
+ qr_solver(sparse_jacobian);
+ event_logger.AddEvent("QRDecomposition");
+
+ if(qr_solver.info() != Eigen::Success) {
+ LOG(ERROR) << "Eigen::SparseQR decomposition failed.";
+ return false;
+ }
+
+ if (qr_solver.rank() < jacobian.num_cols) {
+ LOG(ERROR) << "Jacobian matrix is rank deficient. "
+ << "Number of columns: " << jacobian.num_cols
+ << " rank: " << qr_solver.rank();
+ return false;
+ }
+
+ const int* rows = covariance_matrix_->rows();
+ const int* cols = covariance_matrix_->cols();
+ double* values = covariance_matrix_->mutable_values();
+
+ // Compute the inverse column permutation used by QR factorization.
+ Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic> inverse_permutation =
+ qr_solver.colsPermutation().inverse();
+
+ // The following loop exploits the fact that the i^th column of A^{-1}
+ // is given by the solution to the linear system
+ //
+ // A x = e_i
+ //
+ // where e_i is a vector with e(i) = 1 and all other entries zero.
+ //
+ // Since the covariance matrix is symmetric, the i^th row and column
+ // are equal.
+ const int num_cols = jacobian.num_cols;
+ const int num_threads = options_.num_threads;
+ scoped_array<double> workspace(new double[num_threads * num_cols]);
+
+#pragma omp parallel for num_threads(num_threads) schedule(dynamic)
+ for (int r = 0; r < num_cols; ++r) {
+ const int row_begin = rows[r];
+ const int row_end = rows[r + 1];
+ if (row_end == row_begin) {
+ continue;
+ }
+
+# ifdef CERES_USE_OPENMP
+ int thread_id = omp_get_thread_num();
+# else
+ int thread_id = 0;
+# endif
+
+ double* solution = workspace.get() + thread_id * num_cols;
+ SolveRTRWithSparseRHS<int>(
+ num_cols,
+ qr_solver.matrixR().innerIndexPtr(),
+ qr_solver.matrixR().outerIndexPtr(),
+ &qr_solver.matrixR().data().value(0),
+ inverse_permutation.indices().coeff(r),
+ solution);
+
+ // Assign the values of the computed covariance using the
+ // inverse permutation used in the QR factorization.
+ for (int idx = row_begin; idx < row_end; ++idx) {
+ const int c = cols[idx];
+ values[idx] = solution[inverse_permutation.indices().coeff(c)];
+ }
+ }
+
+ event_logger.AddEvent("Inverse");
+
+ return true;
+}
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/covariance_impl.h b/extern/libmv/third_party/ceres/internal/ceres/covariance_impl.h
index 0e7e2173079..135f4a1d624 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/covariance_impl.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/covariance_impl.h
@@ -64,9 +64,9 @@ class CovarianceImpl {
ProblemImpl* problem);
bool ComputeCovarianceValues();
- bool ComputeCovarianceValuesUsingSparseCholesky();
- bool ComputeCovarianceValuesUsingSparseQR();
bool ComputeCovarianceValuesUsingDenseSVD();
+ bool ComputeCovarianceValuesUsingSuiteSparseQR();
+ bool ComputeCovarianceValuesUsingEigenSparseQR();
const CompressedRowSparseMatrix* covariance_matrix() const {
return covariance_matrix_.get();
diff --git a/extern/libmv/third_party/ceres/internal/ceres/cxsparse.h b/extern/libmv/third_party/ceres/internal/ceres/cxsparse.h
index 1fed82f7866..5868401b961 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/cxsparse.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/cxsparse.h
@@ -38,7 +38,6 @@
#include <vector>
#include "cs.h"
-#include "ceres/internal/port.h"
namespace ceres {
namespace internal {
@@ -130,9 +129,13 @@ class CXSparse {
#else // CERES_NO_CXSPARSE
-class CXSparse {};
typedef void cs_dis;
+class CXSparse {
+ public:
+ void Free(void*) {};
+
+};
#endif // CERES_NO_CXSPARSE
#endif // CERES_INTERNAL_CXSPARSE_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/dynamic_compressed_row_jacobian_writer.cc b/extern/libmv/third_party/ceres/internal/ceres/dynamic_compressed_row_jacobian_writer.cc
index 2f01617749d..b46cb797ff2 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/dynamic_compressed_row_jacobian_writer.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/dynamic_compressed_row_jacobian_writer.cc
@@ -54,8 +54,15 @@ SparseMatrix* DynamicCompressedRowJacobianWriter::CreateJacobian() const {
num_effective_parameters,
0);
- CompressedRowJacobianWriter::PopulateJacobianRowAndColumnBlockVectors(
- program_, jacobian);
+ vector<int>* row_blocks = jacobian->mutable_row_blocks();
+ for (int i = 0; i < jacobian->num_rows(); ++i) {
+ row_blocks->push_back(1);
+ }
+
+ vector<int>* col_blocks = jacobian->mutable_col_blocks();
+ for (int i = 0; i < jacobian->num_cols(); ++i) {
+ col_blocks->push_back(1);
+ }
return jacobian;
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc b/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc
index bca22e6de03..3272848a499 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/gradient_checking_cost_function.cc
@@ -310,6 +310,17 @@ ProblemImpl* CreateGradientCheckingProblemImpl(ProblemImpl* problem_impl,
parameter_blocks);
}
+ // Normally, when a problem is given to the solver, we guarantee
+ // that the state pointers for each parameter block point to the
+ // user provided data. Since we are creating this new problem from a
+ // problem given to us at an arbitrary stage of the solve, we cannot
+ // depend on this being the case, so we explicitly call
+ // SetParameterBlockStatePtrsToUserStatePtrs to ensure that this is
+ // the case.
+ gradient_checking_problem_impl
+ ->mutable_program()
+ ->SetParameterBlockStatePtrsToUserStatePtrs();
+
return gradient_checking_problem_impl;
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/gradient_problem.cc b/extern/libmv/third_party/ceres/internal/ceres/gradient_problem.cc
new file mode 100644
index 00000000000..8f9a842bd89
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/gradient_problem.cc
@@ -0,0 +1,81 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#include "ceres/gradient_problem.h"
+#include "ceres/local_parameterization.h"
+#include "glog/logging.h"
+
+namespace ceres {
+
+GradientProblem::GradientProblem(FirstOrderFunction* function)
+ : function_(function),
+ parameterization_(
+ new IdentityParameterization(function_->NumParameters())),
+ scratch_(new double[function_->NumParameters()]) {
+}
+
+GradientProblem::GradientProblem(FirstOrderFunction* function,
+ LocalParameterization* parameterization)
+ : function_(function),
+ parameterization_(parameterization),
+ scratch_(new double[function_->NumParameters()]) {
+ CHECK_EQ(function_->NumParameters(), parameterization_->GlobalSize());
+}
+
+int GradientProblem::NumParameters() const {
+ return function_->NumParameters();
+}
+
+int GradientProblem::NumLocalParameters() const {
+ return parameterization_->LocalSize();
+}
+
+
+bool GradientProblem::Evaluate(const double* parameters,
+ double* cost,
+ double* gradient) const {
+ if (gradient == NULL) {
+ return function_->Evaluate(parameters, cost, NULL);
+ }
+
+ return (function_->Evaluate(parameters, cost, scratch_.get()) &&
+ parameterization_->MultiplyByJacobian(parameters,
+ 1,
+ scratch_.get(),
+ gradient));
+}
+
+bool GradientProblem::Plus(const double* x,
+ const double* delta,
+ double* x_plus_delta) const {
+ return parameterization_->Plus(x, delta, x_plus_delta);
+}
+
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/gradient_problem_evaluator.h b/extern/libmv/third_party/ceres/internal/ceres/gradient_problem_evaluator.h
new file mode 100644
index 00000000000..20053de2af6
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/gradient_problem_evaluator.h
@@ -0,0 +1,98 @@
+// 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)
+
+#ifndef CERES_INTERNAL_GRADIENT_PROBLEM_EVALUATOR_H_
+#define CERES_INTERNAL_GRADIENT_PROBLEM_EVALUATOR_H_
+
+#include <map>
+#include <string>
+
+#include "ceres/evaluator.h"
+#include "ceres/execution_summary.h"
+#include "ceres/gradient_problem.h"
+#include "ceres/internal/port.h"
+#include "ceres/wall_time.h"
+
+namespace ceres {
+namespace internal {
+
+class GradientProblemEvaluator : public Evaluator {
+ public:
+ explicit GradientProblemEvaluator(const GradientProblem& problem)
+ : problem_(problem) {}
+ virtual ~GradientProblemEvaluator() {}
+ virtual SparseMatrix* CreateJacobian() const { return NULL; }
+ virtual bool Evaluate(const EvaluateOptions& evaluate_options,
+ const double* state,
+ double* cost,
+ double* residuals,
+ double* gradient,
+ SparseMatrix* jacobian) {
+ CHECK(jacobian == NULL);
+ ScopedExecutionTimer total_timer("Evaluator::Total", &execution_summary_);
+ ScopedExecutionTimer call_type_timer(
+ gradient == NULL ? "Evaluator::Cost" : "Evaluator::Gradient",
+ &execution_summary_);
+ return problem_.Evaluate(state, cost, gradient);
+ }
+
+ virtual bool Plus(const double* state,
+ const double* delta,
+ double* state_plus_delta) const {
+ return problem_.Plus(state, delta, state_plus_delta);
+ }
+
+ virtual int NumParameters() const {
+ return problem_.NumParameters();
+ }
+
+ virtual int NumEffectiveParameters() const {
+ return problem_.NumLocalParameters();
+ }
+
+ virtual int NumResiduals() const { return 1; }
+
+ virtual map<string, int> CallStatistics() const {
+ return execution_summary_.calls();
+ }
+
+ virtual map<string, double> TimeStatistics() const {
+ return execution_summary_.times();
+ }
+
+ private:
+ const GradientProblem& problem_;
+ ::ceres::internal::ExecutionSummary execution_summary_;
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_GRADIENT_PROBLEM_EVALUATOR_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/gradient_problem_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/gradient_problem_solver.cc
new file mode 100644
index 00000000000..4024f4cc4e6
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/gradient_problem_solver.cc
@@ -0,0 +1,270 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#include "ceres/gradient_problem_solver.h"
+
+#include "ceres/callbacks.h"
+#include "ceres/gradient_problem.h"
+#include "ceres/gradient_problem_evaluator.h"
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+#include "ceres/map_util.h"
+#include "ceres/minimizer.h"
+#include "ceres/solver.h"
+#include "ceres/solver_utils.h"
+#include "ceres/stringprintf.h"
+#include "ceres/types.h"
+#include "ceres/wall_time.h"
+
+namespace ceres {
+using internal::StringPrintf;
+using internal::StringAppendF;
+
+namespace {
+
+Solver::Options GradientProblemSolverOptionsToSolverOptions(
+ const GradientProblemSolver::Options& options) {
+#define COPY_OPTION(x) solver_options.x = options.x
+
+ Solver::Options solver_options;
+ solver_options.minimizer_type = LINE_SEARCH;
+ COPY_OPTION(line_search_direction_type);
+ COPY_OPTION(line_search_type);
+ COPY_OPTION(nonlinear_conjugate_gradient_type);
+ COPY_OPTION(max_lbfgs_rank);
+ COPY_OPTION(use_approximate_eigenvalue_bfgs_scaling);
+ COPY_OPTION(line_search_interpolation_type);
+ COPY_OPTION(min_line_search_step_size);
+ COPY_OPTION(line_search_sufficient_function_decrease);
+ COPY_OPTION(max_line_search_step_contraction);
+ COPY_OPTION(min_line_search_step_contraction);
+ COPY_OPTION(max_num_line_search_step_size_iterations);
+ COPY_OPTION(max_num_line_search_direction_restarts);
+ COPY_OPTION(line_search_sufficient_curvature_decrease);
+ COPY_OPTION(max_line_search_step_expansion);
+ COPY_OPTION(max_num_iterations);
+ COPY_OPTION(max_solver_time_in_seconds);
+ COPY_OPTION(function_tolerance);
+ COPY_OPTION(gradient_tolerance);
+ COPY_OPTION(logging_type);
+ COPY_OPTION(minimizer_progress_to_stdout);
+ COPY_OPTION(callbacks);
+ return solver_options;
+#undef COPY_OPTION
+}
+
+
+} // namespace
+
+GradientProblemSolver::~GradientProblemSolver() {
+}
+
+void GradientProblemSolver::Solve(const GradientProblemSolver::Options& options,
+ const GradientProblem& problem,
+ double* parameters_ptr,
+ GradientProblemSolver::Summary* summary) {
+ using internal::scoped_ptr;
+ using internal::WallTimeInSeconds;
+ using internal::Minimizer;
+ using internal::GradientProblemEvaluator;
+ using internal::LoggingCallback;
+ using internal::SetSummaryFinalCost;
+
+ double start_time = WallTimeInSeconds();
+ Solver::Options solver_options =
+ GradientProblemSolverOptionsToSolverOptions(options);
+
+ *CHECK_NOTNULL(summary) = Summary();
+ summary->num_parameters = problem.NumParameters();
+ summary->num_local_parameters = problem.NumLocalParameters();
+ summary->line_search_direction_type = options.line_search_direction_type; // NOLINT
+ summary->line_search_interpolation_type = options.line_search_interpolation_type; // NOLINT
+ summary->line_search_type = options.line_search_type;
+ summary->max_lbfgs_rank = options.max_lbfgs_rank;
+ summary->nonlinear_conjugate_gradient_type = options.nonlinear_conjugate_gradient_type; // NOLINT
+
+ // Check validity
+ if (!solver_options.IsValid(&summary->message)) {
+ LOG(ERROR) << "Terminating: " << summary->message;
+ return;
+ }
+
+ // Assuming that the parameter blocks in the program have been
+ Minimizer::Options minimizer_options;
+ minimizer_options = Minimizer::Options(solver_options);
+ minimizer_options.evaluator.reset(new GradientProblemEvaluator(problem));
+
+ scoped_ptr<IterationCallback> logging_callback;
+ if (options.logging_type != SILENT) {
+ logging_callback.reset(
+ new LoggingCallback(LINE_SEARCH, options.minimizer_progress_to_stdout));
+ minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
+ logging_callback.get());
+ }
+
+ scoped_ptr<Minimizer> minimizer(Minimizer::Create(LINE_SEARCH));
+ Vector solution(problem.NumParameters());
+ VectorRef parameters(parameters_ptr, problem.NumParameters());
+ solution = parameters;
+
+ Solver::Summary solver_summary;
+ solver_summary.fixed_cost = 0.0;
+ solver_summary.preprocessor_time_in_seconds = 0.0;
+ solver_summary.postprocessor_time_in_seconds = 0.0;
+
+ minimizer->Minimize(minimizer_options, solution.data(), &solver_summary);
+
+ summary->termination_type = solver_summary.termination_type;
+ summary->message = solver_summary.message;
+ summary->initial_cost = solver_summary.initial_cost;
+ summary->final_cost = solver_summary.final_cost;
+ summary->iterations = solver_summary.iterations;
+
+ if (summary->IsSolutionUsable()) {
+ parameters = solution;
+ SetSummaryFinalCost(summary);
+ }
+
+ const map<string, double>& evaluator_time_statistics =
+ minimizer_options.evaluator->TimeStatistics();
+ summary->cost_evaluation_time_in_seconds =
+ FindWithDefault(evaluator_time_statistics, "Evaluator::Residual", 0.0);
+ summary->gradient_evaluation_time_in_seconds =
+ FindWithDefault(evaluator_time_statistics, "Evaluator::Jacobian", 0.0);
+
+ summary->total_time_in_seconds = WallTimeInSeconds() - start_time;
+}
+
+// Invalid values for most fields, to ensure that we are not
+// accidentally reporting default values.
+GradientProblemSolver::Summary::Summary()
+ : termination_type(FAILURE),
+ message("ceres::GradientProblemSolve was not called."),
+ initial_cost(-1.0),
+ final_cost(-1.0),
+ total_time_in_seconds(-1.0),
+ cost_evaluation_time_in_seconds(-1.0),
+ gradient_evaluation_time_in_seconds(-1.0),
+ num_parameters(-1),
+ num_local_parameters(-1),
+ line_search_direction_type(LBFGS),
+ line_search_type(ARMIJO),
+ line_search_interpolation_type(BISECTION),
+ nonlinear_conjugate_gradient_type(FLETCHER_REEVES),
+ max_lbfgs_rank(-1) {
+}
+
+bool GradientProblemSolver::Summary::IsSolutionUsable() const {
+ return internal::IsSolutionUsable(*this);
+}
+
+string GradientProblemSolver::Summary::BriefReport() const {
+ return StringPrintf("Ceres GradientProblemSolver Report: "
+ "Iterations: %d, "
+ "Initial cost: %e, "
+ "Final cost: %e, "
+ "Termination: %s",
+ static_cast<int>(iterations.size()),
+ initial_cost,
+ final_cost,
+ TerminationTypeToString(termination_type));
+};
+
+string GradientProblemSolver::Summary::FullReport() const {
+ using internal::VersionString;
+
+ string report = string("\nSolver Summary (v " + VersionString() + ")\n\n");
+
+ StringAppendF(&report, "Parameters % 25d\n", num_parameters);
+ if (num_local_parameters != num_parameters) {
+ StringAppendF(&report, "Local parameters % 25d\n",
+ num_local_parameters);
+ }
+
+ string line_search_direction_string;
+ if (line_search_direction_type == LBFGS) {
+ line_search_direction_string = StringPrintf("LBFGS (%d)", max_lbfgs_rank);
+ } else if (line_search_direction_type == NONLINEAR_CONJUGATE_GRADIENT) {
+ line_search_direction_string =
+ NonlinearConjugateGradientTypeToString(
+ nonlinear_conjugate_gradient_type);
+ } else {
+ line_search_direction_string =
+ LineSearchDirectionTypeToString(line_search_direction_type);
+ }
+
+ StringAppendF(&report, "Line search direction %19s\n",
+ line_search_direction_string.c_str());
+
+ const string line_search_type_string =
+ StringPrintf("%s %s",
+ LineSearchInterpolationTypeToString(
+ line_search_interpolation_type),
+ LineSearchTypeToString(line_search_type));
+ StringAppendF(&report, "Line search type %19s\n",
+ line_search_type_string.c_str());
+ StringAppendF(&report, "\n");
+
+ StringAppendF(&report, "\nCost:\n");
+ StringAppendF(&report, "Initial % 30e\n", initial_cost);
+ if (termination_type != FAILURE &&
+ termination_type != USER_FAILURE) {
+ StringAppendF(&report, "Final % 30e\n", final_cost);
+ StringAppendF(&report, "Change % 30e\n",
+ initial_cost - final_cost);
+ }
+
+ StringAppendF(&report, "\nMinimizer iterations % 16d\n",
+ static_cast<int>(iterations.size()));
+
+ StringAppendF(&report, "\nTime (in seconds):\n");
+
+ StringAppendF(&report, "\n Cost evaluation %23.3f\n",
+ cost_evaluation_time_in_seconds);
+ StringAppendF(&report, " Gradient evaluation %23.3f\n",
+ gradient_evaluation_time_in_seconds);
+
+ StringAppendF(&report, "Total %25.3f\n\n",
+ total_time_in_seconds);
+
+ StringAppendF(&report, "Termination: %25s (%s)\n",
+ TerminationTypeToString(termination_type), message.c_str());
+ return report;
+};
+
+void Solve(const GradientProblemSolver::Options& options,
+ const GradientProblem& problem,
+ double* parameters,
+ GradientProblemSolver::Summary* summary) {
+ GradientProblemSolver solver;
+ solver.Solve(options, problem, parameters, summary);
+}
+
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/graph.h b/extern/libmv/third_party/ceres/internal/ceres/graph.h
index 5f92d4d4df2..f639d15323d 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/graph.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/graph.h
@@ -43,13 +43,75 @@
namespace ceres {
namespace internal {
-// A weighted undirected graph templated over the vertex ids. Vertex
-// should be hashable and comparable.
+// A unweighted undirected graph templated over the vertex ids. Vertex
+// should be hashable.
template <typename Vertex>
class Graph {
public:
Graph() {}
+ // Add a vertex.
+ void AddVertex(const Vertex& vertex) {
+ if (vertices_.insert(vertex).second) {
+ edges_[vertex] = HashSet<Vertex>();
+ }
+ }
+
+ bool RemoveVertex(const Vertex& vertex) {
+ if (vertices_.find(vertex) == vertices_.end()) {
+ return false;
+ }
+
+ vertices_.erase(vertex);
+ const HashSet<Vertex>& sinks = edges_[vertex];
+ for (typename HashSet<Vertex>::const_iterator it = sinks.begin();
+ it != sinks.end(); ++it) {
+ edges_[*it].erase(vertex);
+ }
+
+ edges_.erase(vertex);
+ return true;
+ }
+
+ // Add an edge between the vertex1 and vertex2. Calling AddEdge on a
+ // pair of vertices which do not exist in the graph yet will result
+ // in undefined behavior.
+ //
+ // It is legal to call this method repeatedly for the same set of
+ // vertices.
+ void AddEdge(const Vertex& vertex1, const Vertex& vertex2) {
+ DCHECK(vertices_.find(vertex1) != vertices_.end());
+ DCHECK(vertices_.find(vertex2) != vertices_.end());
+
+ if (edges_[vertex1].insert(vertex2).second) {
+ edges_[vertex2].insert(vertex1);
+ }
+ }
+
+ // Calling Neighbors on a vertex not in the graph will result in
+ // undefined behaviour.
+ const HashSet<Vertex>& Neighbors(const Vertex& vertex) const {
+ return FindOrDie(edges_, vertex);
+ }
+
+ const HashSet<Vertex>& vertices() const {
+ return vertices_;
+ }
+
+ private:
+ HashSet<Vertex> vertices_;
+ HashMap<Vertex, HashSet<Vertex> > edges_;
+
+ CERES_DISALLOW_COPY_AND_ASSIGN(Graph);
+};
+
+// A weighted undirected graph templated over the vertex ids. Vertex
+// should be hashable and comparable.
+template <typename Vertex>
+class WeightedGraph {
+ public:
+ WeightedGraph() {}
+
// Add a weighted vertex. If the vertex already exists in the graph,
// its weight is set to the new weight.
void AddVertex(const Vertex& vertex, double weight) {
@@ -152,7 +214,7 @@ class Graph {
HashMap<Vertex, HashSet<Vertex> > edges_;
HashMap<pair<Vertex, Vertex>, double> edge_weights_;
- CERES_DISALLOW_COPY_AND_ASSIGN(Graph);
+ CERES_DISALLOW_COPY_AND_ASSIGN(WeightedGraph);
};
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h b/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h
index ca3a2fe1a88..fb75e2f45f2 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/graph_algorithms.h
@@ -38,6 +38,7 @@
#include <utility>
#include "ceres/collections_port.h"
#include "ceres/graph.h"
+#include "ceres/wall_time.h"
#include "glog/logging.h"
namespace ceres {
@@ -270,11 +271,11 @@ Vertex FindConnectedComponent(const Vertex& vertex,
// spanning forest, or a collection of linear paths that span the
// graph G.
template <typename Vertex>
-Graph<Vertex>*
-Degree2MaximumSpanningForest(const Graph<Vertex>& graph) {
+WeightedGraph<Vertex>*
+Degree2MaximumSpanningForest(const WeightedGraph<Vertex>& graph) {
// Array of edges sorted in decreasing order of their weights.
vector<pair<double, pair<Vertex, Vertex> > > weighted_edges;
- Graph<Vertex>* forest = new Graph<Vertex>();
+ WeightedGraph<Vertex>* forest = new WeightedGraph<Vertex>();
// Disjoint-set to keep track of the connected components in the
// maximum spanning tree.
diff --git a/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc
index 6de410bf80f..0cf08fef5f7 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/iterative_schur_complement_solver.cc
@@ -101,6 +101,7 @@ LinearSolver::Summary IterativeSchurComplementSolver::SolveImpl(
// complement matrix with the block diagonal of the matrix F'F as
// the preconditioner.
LinearSolver::Options cg_options;
+ cg_options.min_num_iterations = options_.min_num_iterations;
cg_options.max_num_iterations = options_.max_num_iterations;
ConjugateGradientsSolver cg_solver(cg_options);
LinearSolver::PerSolveOptions cg_per_solve_options;
diff --git a/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc b/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc
index e04c65b63be..dddcecdb196 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search_direction.cc
@@ -65,7 +65,7 @@ class NonlinearConjugateGradient : public LineSearchDirection {
case FLETCHER_REEVES:
beta = current.gradient_squared_norm / previous.gradient_squared_norm;
break;
- case POLAK_RIBIRERE:
+ case POLAK_RIBIERE:
gradient_change = current.gradient - previous.gradient;
beta = (current.gradient.dot(gradient_change) /
previous.gradient_squared_norm);
diff --git a/extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.cc b/extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.cc
index ae77a73805c..ad28ffb137d 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search_minimizer.cc
@@ -103,7 +103,7 @@ void LineSearchMinimizer::Minimize(const Minimizer::Options& options,
double start_time = WallTimeInSeconds();
double iteration_start_time = start_time;
- Evaluator* evaluator = CHECK_NOTNULL(options.evaluator);
+ Evaluator* evaluator = CHECK_NOTNULL(options.evaluator.get());
const int num_parameters = evaluator->NumParameters();
const int num_effective_parameters = evaluator->NumEffectiveParameters();
@@ -375,7 +375,6 @@ void LineSearchMinimizer::Minimize(const Minimizer::Options& options,
WallTimeInSeconds() - start_time
+ summary->preprocessor_time_in_seconds;
- summary->iterations.push_back(iteration_summary);
++summary->num_successful_steps;
if (iteration_summary.gradient_max_norm <= options.gradient_tolerance) {
@@ -401,6 +400,8 @@ void LineSearchMinimizer::Minimize(const Minimizer::Options& options,
VLOG_IF(1, is_not_silent) << "Terminating: " << summary->message;
break;
}
+
+ summary->iterations.push_back(iteration_summary);
}
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/line_search_preprocessor.cc b/extern/libmv/third_party/ceres/internal/ceres/line_search_preprocessor.cc
new file mode 100644
index 00000000000..bf17dee351d
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search_preprocessor.cc
@@ -0,0 +1,106 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#include "ceres/line_search_preprocessor.h"
+
+#include <numeric>
+#include <string>
+#include "ceres/evaluator.h"
+#include "ceres/minimizer.h"
+#include "ceres/problem_impl.h"
+#include "ceres/program.h"
+#include "ceres/wall_time.h"
+
+namespace ceres {
+namespace internal {
+namespace {
+
+bool IsProgramValid(const Program& program, string* error) {
+ if (program.IsBoundsConstrained()) {
+ *error = "LINE_SEARCH Minimizer does not support bounds.";
+ return false;
+ }
+ return program.ParameterBlocksAreFinite(error);
+}
+
+bool SetupEvaluator(PreprocessedProblem* pp) {
+ pp->evaluator_options = Evaluator::Options();
+ // This ensures that we get a Block Jacobian Evaluator without any
+ // requirement on orderings.
+ pp->evaluator_options.linear_solver_type = CGNR;
+ pp->evaluator_options.num_eliminate_blocks = 0;
+ pp->evaluator_options.num_threads = pp->options.num_threads;
+ pp->evaluator.reset(Evaluator::Create(pp->evaluator_options,
+ pp->reduced_program.get(),
+ &pp->error));
+ return (pp->evaluator.get() != NULL);
+}
+
+} // namespace
+
+LineSearchPreprocessor::~LineSearchPreprocessor() {
+}
+
+bool LineSearchPreprocessor::Preprocess(const Solver::Options& options,
+ ProblemImpl* problem,
+ PreprocessedProblem* pp) {
+ CHECK_NOTNULL(pp);
+ pp->options = options;
+ ChangeNumThreadsIfNeeded(&pp->options);
+
+ pp->problem = problem;
+ Program* program = problem->mutable_program();
+ if (!IsProgramValid(*program, &pp->error)) {
+ return false;
+ }
+
+ pp->reduced_program.reset(
+ program->CreateReducedProgram(&pp->removed_parameter_blocks,
+ &pp->fixed_cost,
+ &pp->error));
+
+ if (pp->reduced_program.get() == NULL) {
+ return false;
+ }
+
+ if (pp->reduced_program->NumParameterBlocks() == 0) {
+ return true;
+ }
+
+ if (!SetupEvaluator(pp)) {
+ return false;
+ }
+
+ SetupCommonMinimizerOptions(pp);
+ return true;
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/line_search_preprocessor.h b/extern/libmv/third_party/ceres/internal/ceres/line_search_preprocessor.h
new file mode 100644
index 00000000000..54b968bc29e
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/line_search_preprocessor.h
@@ -0,0 +1,50 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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: sameragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_INTERNAL_LINE_SEARCH_PREPROCESSOR_H_
+#define CERES_INTERNAL_LINE_SEARCH_PREPROCESSOR_H_
+
+#include "ceres/preprocessor.h"
+
+namespace ceres {
+namespace internal {
+
+class LineSearchPreprocessor : public Preprocessor {
+ public:
+ virtual ~LineSearchPreprocessor();
+ virtual bool Preprocess(const Solver::Options& options,
+ ProblemImpl* problem,
+ PreprocessedProblem* preprocessed_problem);
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_LINE_SEARCH_PREPROCESSOR_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_solver.cc b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.cc
index 08c3ba110d0..e479b751363 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/linear_solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.cc
@@ -45,26 +45,48 @@ namespace internal {
LinearSolver::~LinearSolver() {
}
+LinearSolverType LinearSolver::LinearSolverForZeroEBlocks(
+ LinearSolverType linear_solver_type) {
+ if (!IsSchurType(linear_solver_type)) {
+ return linear_solver_type;
+ }
+
+ if (linear_solver_type == SPARSE_SCHUR) {
+ return SPARSE_NORMAL_CHOLESKY;
+ }
+
+ if (linear_solver_type == DENSE_SCHUR) {
+ // TODO(sameeragarwal): This is probably not a great choice.
+ // Ideally, we should have a DENSE_NORMAL_CHOLESKY, that can take
+ // a BlockSparseMatrix as input.
+ return DENSE_QR;
+ }
+
+ if (linear_solver_type == ITERATIVE_SCHUR) {
+ return CGNR;
+ }
+
+ return linear_solver_type;
+}
+
LinearSolver* LinearSolver::Create(const LinearSolver::Options& options) {
switch (options.type) {
case CGNR:
return new CgnrSolver(options);
case SPARSE_NORMAL_CHOLESKY:
-#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
- LOG(WARNING) << "SPARSE_NORMAL_CHOLESKY is not available. Please "
- << "build Ceres with SuiteSparse or CXSparse. "
- << "Returning NULL.";
+#if defined(CERES_NO_SUITESPARSE) && \
+ defined(CERES_NO_CXSPARSE) && \
+ !defined(CERES_USE_EIGEN_SPARSE)
return NULL;
#else
return new SparseNormalCholeskySolver(options);
#endif
case SPARSE_SCHUR:
-#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
- LOG(WARNING) << "SPARSE_SCHUR is not available. Please "
- << "build Ceres with SuiteSparse or CXSparse. "
- << "Returning NULL.";
+#if defined(CERES_NO_SUITESPARSE) && \
+ defined(CERES_NO_CXSPARSE) && \
+ !defined(CERES_USE_EIGEN_SPARSE)
return NULL;
#else
return new SparseSchurComplementSolver(options);
@@ -74,7 +96,11 @@ LinearSolver* LinearSolver::Create(const LinearSolver::Options& options) {
return new DenseSchurComplementSolver(options);
case ITERATIVE_SCHUR:
- return new IterativeSchurComplementSolver(options);
+ if (options.use_explicit_schur_complement) {
+ return new SparseSchurComplementSolver(options);
+ } else {
+ return new IterativeSchurComplementSolver(options);
+ }
case DENSE_QR:
return new DenseQRSolver(options);
diff --git a/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h
index f091bc5b187..5f59765f074 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/linear_solver.h
@@ -99,6 +99,7 @@ class LinearSolver {
sparse_linear_algebra_library_type(SUITE_SPARSE),
use_postordering(false),
dynamic_sparsity(false),
+ use_explicit_schur_complement(false),
min_num_iterations(1),
max_num_iterations(1),
num_threads(1),
@@ -114,9 +115,10 @@ class LinearSolver {
DenseLinearAlgebraLibraryType dense_linear_algebra_library_type;
SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type;
- // See solver.h for information about this flag.
+ // See solver.h for information about these flags.
bool use_postordering;
bool dynamic_sparsity;
+ bool use_explicit_schur_complement;
// Number of internal iterations that the solver uses. This
// parameter only makes sense for iterative solvers like CG.
@@ -274,6 +276,14 @@ class LinearSolver {
string message;
};
+ // If the optimization problem is such that there are no remaining
+ // e-blocks, a Schur type linear solver cannot be used. If the
+ // linear solver is of Schur type, this function implements a policy
+ // to select an alternate nearest linear solver to the one selected
+ // by the user. The input linear_solver_type is returned otherwise.
+ static LinearSolverType LinearSolverForZeroEBlocks(
+ LinearSolverType linear_solver_type);
+
virtual ~LinearSolver();
// Solve Ax = b.
diff --git a/extern/libmv/third_party/ceres/internal/ceres/local_parameterization.cc b/extern/libmv/third_party/ceres/internal/ceres/local_parameterization.cc
index 26e7f4908a4..a4832c57443 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/local_parameterization.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/local_parameterization.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2014 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,23 @@
namespace ceres {
+LocalParameterization::~LocalParameterization() {
+}
+
+bool LocalParameterization::MultiplyByJacobian(const double* x,
+ const int num_rows,
+ const double* global_matrix,
+ double* local_matrix) const {
+ Matrix jacobian(GlobalSize(), LocalSize());
+ if (!ComputeJacobian(x, jacobian.data())) {
+ return false;
+ }
+
+ MatrixRef(local_matrix, num_rows, LocalSize()) =
+ ConstMatrixRef(global_matrix, num_rows, GlobalSize()) * jacobian;
+ return true;
+}
+
IdentityParameterization::IdentityParameterization(const int size)
: size_(size) {
CHECK_GT(size, 0);
@@ -55,6 +72,16 @@ bool IdentityParameterization::ComputeJacobian(const double* x,
return true;
}
+bool IdentityParameterization::MultiplyByJacobian(const double* x,
+ const int num_cols,
+ const double* global_matrix,
+ double* local_matrix) const {
+ std::copy(global_matrix,
+ global_matrix + num_cols * GlobalSize(),
+ local_matrix);
+ return true;
+}
+
SubsetParameterization::SubsetParameterization(
int size,
const vector<int>& constant_parameters)
@@ -108,6 +135,21 @@ bool SubsetParameterization::ComputeJacobian(const double* x,
return true;
}
+bool SubsetParameterization::MultiplyByJacobian(const double* x,
+ const int num_rows,
+ const double* global_matrix,
+ double* local_matrix) const {
+ for (int row = 0; row < num_rows; ++row) {
+ for (int col = 0, j = 0; col < constancy_mask_.size(); ++col) {
+ if (!constancy_mask_[col]) {
+ local_matrix[row * LocalSize() + j++] =
+ global_matrix[row * GlobalSize() + col];
+ }
+ }
+ }
+ return true;
+}
+
bool QuaternionParameterization::Plus(const double* x,
const double* delta,
double* x_plus_delta) const {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/loss_function.cc b/extern/libmv/third_party/ceres/internal/ceres/loss_function.cc
index b948f289f21..62b545be12f 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/loss_function.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/loss_function.cc
@@ -34,13 +34,14 @@
#include <cmath>
#include <cstddef>
+#include <limits>
namespace ceres {
void TrivialLoss::Evaluate(double s, double rho[3]) const {
rho[0] = s;
- rho[1] = 1;
- rho[2] = 0;
+ rho[1] = 1.0;
+ rho[2] = 0.0;
}
void HuberLoss::Evaluate(double s, double rho[3]) const {
@@ -48,32 +49,32 @@ void HuberLoss::Evaluate(double s, double rho[3]) const {
// Outlier region.
// 'r' is always positive.
const double r = sqrt(s);
- rho[0] = 2 * a_ * r - b_;
- rho[1] = a_ / r;
- rho[2] = - rho[1] / (2 * s);
+ rho[0] = 2.0 * a_ * r - b_;
+ rho[1] = std::max(std::numeric_limits<double>::min(), a_ / r);
+ rho[2] = - rho[1] / (2.0 * s);
} else {
// Inlier region.
rho[0] = s;
- rho[1] = 1;
- rho[2] = 0;
+ rho[1] = 1.0;
+ rho[2] = 0.0;
}
}
void SoftLOneLoss::Evaluate(double s, double rho[3]) const {
- const double sum = 1 + s * c_;
+ const double sum = 1.0 + s * c_;
const double tmp = sqrt(sum);
// 'sum' and 'tmp' are always positive, assuming that 's' is.
- rho[0] = 2 * b_ * (tmp - 1);
- rho[1] = 1 / tmp;
- rho[2] = - (c_ * rho[1]) / (2 * sum);
+ rho[0] = 2.0 * b_ * (tmp - 1.0);
+ rho[1] = std::max(std::numeric_limits<double>::min(), 1.0 / tmp);
+ rho[2] = - (c_ * rho[1]) / (2.0 * sum);
}
void CauchyLoss::Evaluate(double s, double rho[3]) const {
- const double sum = 1 + s * c_;
- const double inv = 1 / sum;
+ const double sum = 1.0 + s * c_;
+ const double inv = 1.0 / sum;
// 'sum' and 'inv' are always positive, assuming that 's' is.
rho[0] = b_ * log(sum);
- rho[1] = inv;
+ rho[1] = std::max(std::numeric_limits<double>::min(), inv);
rho[2] = - c_ * (inv * inv);
}
@@ -82,8 +83,8 @@ void ArctanLoss::Evaluate(double s, double rho[3]) const {
const double inv = 1 / sum;
// 'sum' and 'inv' are always positive.
rho[0] = a_ * atan2(s, a_);
- rho[1] = inv;
- rho[2] = -2 * s * b_ * (inv * inv);
+ rho[1] = std::max(std::numeric_limits<double>::min(), inv);
+ rho[2] = -2.0 * s * b_ * (inv * inv);
}
TolerantLoss::TolerantLoss(double a, double b)
@@ -108,7 +109,7 @@ void TolerantLoss::Evaluate(double s, double rho[3]) const {
} else {
const double e_x = exp(x);
rho[0] = b_ * log(1.0 + e_x) - c_;
- rho[1] = e_x / (1.0 + e_x);
+ rho[1] = std::max(std::numeric_limits<double>::min(), e_x / (1.0 + e_x));
rho[2] = 0.5 / (b_ * (1.0 + cosh(x)));
}
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/minimizer.cc b/extern/libmv/third_party/ceres/internal/ceres/minimizer.cc
index 6c3b68dbbc2..558921b8441 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/minimizer.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/minimizer.cc
@@ -28,13 +28,29 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
+#include "ceres/line_search_minimizer.h"
#include "ceres/minimizer.h"
+#include "ceres/trust_region_minimizer.h"
#include "ceres/types.h"
#include "glog/logging.h"
namespace ceres {
namespace internal {
+Minimizer* Minimizer::Create(MinimizerType minimizer_type) {
+ if (minimizer_type == TRUST_REGION) {
+ return new TrustRegionMinimizer;
+ }
+
+ if (minimizer_type == LINE_SEARCH) {
+ return new LineSearchMinimizer;
+ }
+
+ LOG(FATAL) << "Unknown minimizer_type: " << minimizer_type;
+ return NULL;
+}
+
+
Minimizer::~Minimizer() {}
bool Minimizer::RunCallbacks(const Minimizer::Options& options,
diff --git a/extern/libmv/third_party/ceres/internal/ceres/minimizer.h b/extern/libmv/third_party/ceres/internal/ceres/minimizer.h
index f1da3f704fa..dabf07e583a 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/minimizer.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/minimizer.h
@@ -41,9 +41,10 @@ namespace ceres {
namespace internal {
class Evaluator;
-class LinearSolver;
class SparseMatrix;
class TrustRegionStrategy;
+class CoordinateDescentMinimizer;
+class LinearSolver;
// Interface for non-linear least squares solvers.
class Minimizer {
@@ -107,14 +108,10 @@ class Minimizer {
options.line_search_sufficient_curvature_decrease;
max_line_search_step_expansion =
options.max_line_search_step_expansion;
- is_silent = (options.logging_type == SILENT);
- evaluator = NULL;
- trust_region_strategy = NULL;
- jacobian = NULL;
- callbacks = options.callbacks;
- inner_iteration_minimizer = NULL;
inner_iteration_tolerance = options.inner_iteration_tolerance;
+ is_silent = (options.logging_type == SILENT);
is_constrained = false;
+ callbacks = options.callbacks;
}
int max_num_iterations;
@@ -154,10 +151,14 @@ class Minimizer {
int max_num_line_search_direction_restarts;
double line_search_sufficient_curvature_decrease;
double max_line_search_step_expansion;
+ double inner_iteration_tolerance;
// If true, then all logging is disabled.
bool is_silent;
+ // Use a bounds constrained optimization algorithm.
+ bool is_constrained;
+
// List of callbacks that are executed by the Minimizer at the end
// of each iteration.
//
@@ -165,27 +166,23 @@ class Minimizer {
vector<IterationCallback*> callbacks;
// Object responsible for evaluating the cost, residuals and
- // Jacobian matrix. The Options struct does not own this pointer.
- Evaluator* evaluator;
+ // Jacobian matrix.
+ shared_ptr<Evaluator> evaluator;
// Object responsible for actually computing the trust region
- // step, and sizing the trust region radius. The Options struct
- // does not own this pointer.
- TrustRegionStrategy* trust_region_strategy;
+ // step, and sizing the trust region radius.
+ shared_ptr<TrustRegionStrategy> trust_region_strategy;
// Object holding the Jacobian matrix. It is assumed that the
// sparsity structure of the matrix has already been initialized
// and will remain constant for the life time of the
- // optimization. The Options struct does not own this pointer.
- SparseMatrix* jacobian;
+ // optimization.
+ shared_ptr<SparseMatrix> jacobian;
- Minimizer* inner_iteration_minimizer;
- double inner_iteration_tolerance;
-
- // Use a bounds constrained optimization algorithm.
- bool is_constrained;
+ shared_ptr<CoordinateDescentMinimizer> inner_iteration_minimizer;
};
+ static Minimizer* Create(MinimizerType minimizer_type);
static bool RunCallbacks(const Options& options,
const IterationSummary& iteration_summary,
Solver::Summary* summary);
diff --git a/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.cc b/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.cc
index 190715bee43..1525de90d60 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.cc
@@ -37,6 +37,7 @@
#include "ceres/parameter_block.h"
#include "ceres/program.h"
#include "ceres/residual_block.h"
+#include "ceres/wall_time.h"
#include "glog/logging.h"
namespace ceres {
@@ -45,8 +46,10 @@ namespace internal {
int ComputeStableSchurOrdering(const Program& program,
vector<ParameterBlock*>* ordering) {
CHECK_NOTNULL(ordering)->clear();
-
+ EventLogger event_logger("ComputeStableSchurOrdering");
scoped_ptr<Graph< ParameterBlock*> > graph(CreateHessianGraph(program));
+ event_logger.AddEvent("CreateHessianGraph");
+
const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
const HashSet<ParameterBlock*>& vertices = graph->vertices();
for (int i = 0; i < parameter_blocks.size(); ++i) {
@@ -54,8 +57,10 @@ int ComputeStableSchurOrdering(const Program& program,
ordering->push_back(parameter_blocks[i]);
}
}
+ event_logger.AddEvent("Preordering");
int independent_set_size = StableIndependentSetOrdering(*graph, ordering);
+ event_logger.AddEvent("StableIndependentSet");
// Add the excluded blocks to back of the ordering vector.
for (int i = 0; i < parameter_blocks.size(); ++i) {
@@ -64,6 +69,7 @@ int ComputeStableSchurOrdering(const Program& program,
ordering->push_back(parameter_block);
}
}
+ event_logger.AddEvent("ConstantParameterBlocks");
return independent_set_size;
}
@@ -109,8 +115,7 @@ void ComputeRecursiveIndependentSetOrdering(const Program& program,
}
}
-Graph<ParameterBlock*>*
-CreateHessianGraph(const Program& program) {
+Graph<ParameterBlock*>* CreateHessianGraph(const Program& program) {
Graph<ParameterBlock*>* graph = CHECK_NOTNULL(new Graph<ParameterBlock*>);
const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
for (int i = 0; i < parameter_blocks.size(); ++i) {
@@ -144,5 +149,21 @@ CreateHessianGraph(const Program& program) {
return graph;
}
+void OrderingToGroupSizes(const ParameterBlockOrdering* ordering,
+ vector<int>* group_sizes) {
+ CHECK_NOTNULL(group_sizes)->clear();
+ if (ordering == NULL) {
+ return;
+ }
+
+ const map<int, set<double*> >& group_to_elements =
+ ordering->group_to_elements();
+ for (map<int, set<double*> >::const_iterator it = group_to_elements.begin();
+ it != group_to_elements.end();
+ ++it) {
+ group_sizes->push_back(it->second.size());
+ }
+}
+
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.h b/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.h
index 4675cb8dc7c..5de99511138 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/parameter_block_ordering.h
@@ -78,6 +78,11 @@ void ComputeRecursiveIndependentSetOrdering(const Program& program,
// parameter blocks, if they co-occur in a residual block.
Graph<ParameterBlock*>* CreateHessianGraph(const Program& program);
+// Iterate over each of the groups in order of their priority and fill
+// summary with their sizes.
+void OrderingToGroupSizes(const ParameterBlockOrdering* ordering,
+ vector<int>* group_sizes);
+
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/preconditioner.cc b/extern/libmv/third_party/ceres/internal/ceres/preconditioner.cc
index 505a47d3d61..062347fccc1 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/preconditioner.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/preconditioner.cc
@@ -37,6 +37,16 @@ namespace internal {
Preconditioner::~Preconditioner() {
}
+PreconditionerType Preconditioner::PreconditionerForZeroEBlocks(
+ PreconditionerType preconditioner_type) {
+ if (preconditioner_type == SCHUR_JACOBI ||
+ preconditioner_type == CLUSTER_JACOBI ||
+ preconditioner_type == CLUSTER_TRIDIAGONAL) {
+ return JACOBI;
+ }
+ return preconditioner_type;
+}
+
SparseMatrixPreconditionerWrapper::SparseMatrixPreconditionerWrapper(
const SparseMatrix* matrix)
: matrix_(CHECK_NOTNULL(matrix)) {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h
index 21cbc00b542..e8d5994269a 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/preconditioner.h
@@ -36,6 +36,7 @@
#include "ceres/compressed_row_sparse_matrix.h"
#include "ceres/linear_operator.h"
#include "ceres/sparse_matrix.h"
+#include "ceres/types.h"
namespace ceres {
namespace internal {
@@ -95,6 +96,14 @@ class Preconditioner : public LinearOperator {
int f_block_size;
};
+ // If the optimization problem is such that there are no remaining
+ // e-blocks, ITERATIVE_SCHUR with a Schur type preconditioner cannot
+ // be used. This function returns JACOBI if a preconditioner for
+ // ITERATIVE_SCHUR is used. The input preconditioner_type is
+ // returned otherwise.
+ static PreconditionerType PreconditionerForZeroEBlocks(
+ PreconditionerType preconditioner_type);
+
virtual ~Preconditioner();
// Update the numerical value of the preconditioner for the linear
diff --git a/extern/libmv/third_party/ceres/internal/ceres/preprocessor.cc b/extern/libmv/third_party/ceres/internal/ceres/preprocessor.cc
new file mode 100644
index 00000000000..318c5e2ebef
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/preprocessor.cc
@@ -0,0 +1,113 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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: sameragarwal@google.com (Sameer Agarwal)
+
+#include "ceres/callbacks.h"
+#include "ceres/gradient_checking_cost_function.h"
+#include "ceres/line_search_preprocessor.h"
+#include "ceres/preprocessor.h"
+#include "ceres/problem_impl.h"
+#include "ceres/solver.h"
+#include "ceres/trust_region_preprocessor.h"
+
+namespace ceres {
+namespace internal {
+
+Preprocessor* Preprocessor::Create(MinimizerType minimizer_type) {
+ if (minimizer_type == TRUST_REGION) {
+ return new TrustRegionPreprocessor;
+ }
+
+ if (minimizer_type == LINE_SEARCH) {
+ return new LineSearchPreprocessor;
+ }
+
+ LOG(FATAL) << "Unknown minimizer_type: " << minimizer_type;
+ return NULL;
+}
+
+Preprocessor::~Preprocessor() {
+}
+
+void ChangeNumThreadsIfNeeded(Solver::Options* options) {
+#ifndef CERES_USE_OPENMP
+ if (options->num_threads > 1) {
+ LOG(WARNING)
+ << "OpenMP support is not compiled into this binary; "
+ << "only options.num_threads = 1 is supported. Switching "
+ << "to single threaded mode.";
+ options->num_threads = 1;
+ }
+
+ // Only the Trust Region solver currently uses a linear solver.
+ if (options->minimizer_type == TRUST_REGION &&
+ options->num_linear_solver_threads > 1) {
+ LOG(WARNING)
+ << "OpenMP support is not compiled into this binary; "
+ << "only options.num_linear_solver_threads=1 is supported. Switching "
+ << "to single threaded mode.";
+ options->num_linear_solver_threads = 1;
+ }
+#endif // CERES_USE_OPENMP
+}
+
+void SetupCommonMinimizerOptions(PreprocessedProblem* pp) {
+ const Solver::Options& options = pp->options;
+ Program* program = pp->reduced_program.get();
+
+ // Assuming that the parameter blocks in the program have been
+ // reordered as needed, extract them into a contiguous vector.
+ pp->reduced_parameters.resize(program->NumParameters());
+ double* reduced_parameters = pp->reduced_parameters.data();
+ program->ParameterBlocksToStateVector(reduced_parameters);
+
+ Minimizer::Options& minimizer_options = pp->minimizer_options;
+ minimizer_options = Minimizer::Options(options);
+ minimizer_options.evaluator = pp->evaluator;
+
+ if (options.logging_type != SILENT) {
+ pp->logging_callback.reset(
+ new LoggingCallback(options.minimizer_type,
+ options.minimizer_progress_to_stdout));
+ minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
+ pp->logging_callback.get());
+ }
+
+ if (options.update_state_every_iteration) {
+ pp->state_updating_callback.reset(
+ new StateUpdatingCallback(program, reduced_parameters));
+ // This must get pushed to the front of the callbacks so that it
+ // is run before any of the user callbacks.
+ minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
+ pp->state_updating_callback.get());
+ }
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/preprocessor.h b/extern/libmv/third_party/ceres/internal/ceres/preprocessor.h
new file mode 100644
index 00000000000..b4ca5b11747
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/preprocessor.h
@@ -0,0 +1,119 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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: sameragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_INTERNAL_PREPROCESSOR_H_
+#define CERES_INTERNAL_PREPROCESSOR_H_
+
+#include "ceres/coordinate_descent_minimizer.h"
+#include "ceres/evaluator.h"
+#include "ceres/internal/eigen.h"
+#include "ceres/internal/port.h"
+#include "ceres/internal/scoped_ptr.h"
+#include "ceres/iteration_callback.h"
+#include "ceres/linear_solver.h"
+#include "ceres/minimizer.h"
+#include "ceres/problem_impl.h"
+#include "ceres/program.h"
+#include "ceres/solver.h"
+
+namespace ceres {
+namespace internal {
+
+struct PreprocessedProblem;
+
+// Given a Problem object and a Solver::Options object indicating the
+// configuration of the solver, the job of the Preprocessor is to
+// analyze the Problem and perform the setup needed to solve it using
+// the desired Minimization algorithm. The setup involves removing
+// redundancies in the input problem (inactive parameter and residual
+// blocks), finding fill reducing orderings as needed, configuring and
+// creating various objects needed by the Minimizer to solve the
+// problem such as an evaluator, a linear solver etc.
+//
+// Each Minimizer (LineSearchMinimizer and TrustRegionMinimizer) comes
+// with a corresponding Preprocessor (LineSearchPreprocessor and
+// TrustRegionPreprocessor) that knows about its needs and performs
+// the preprocessing needed.
+//
+// The output of the Preprocessor is stored in a PreprocessedProblem
+// object.
+class Preprocessor {
+public:
+ // Factory.
+ static Preprocessor* Create(MinimizerType minimizer_type);
+ virtual ~Preprocessor();
+ virtual bool Preprocess(const Solver::Options& options,
+ ProblemImpl* problem,
+ PreprocessedProblem* pp) = 0;
+};
+
+// A PreprocessedProblem is the result of running the Preprocessor on
+// a Problem and Solver::Options object.
+struct PreprocessedProblem {
+ PreprocessedProblem()
+ : fixed_cost(0.0) {
+ }
+
+ string error;
+ Solver::Options options;
+ LinearSolver::Options linear_solver_options;
+ Evaluator::Options evaluator_options;
+ Minimizer::Options minimizer_options;
+
+ ProblemImpl* problem;
+ scoped_ptr<ProblemImpl> gradient_checking_problem;
+ scoped_ptr<Program> reduced_program;
+ scoped_ptr<LinearSolver> linear_solver;
+ scoped_ptr<IterationCallback> logging_callback;
+ scoped_ptr<IterationCallback> state_updating_callback;
+
+ shared_ptr<Evaluator> evaluator;
+ shared_ptr<CoordinateDescentMinimizer> inner_iteration_minimizer;
+
+ vector<double*> removed_parameter_blocks;
+ Vector reduced_parameters;
+ double fixed_cost;
+};
+
+// Common functions used by various preprocessors.
+
+// If OpenMP support is not available and user has requested more than
+// one thread, then set the *_num_threads options as needed to 1.
+void ChangeNumThreadsIfNeeded(Solver::Options* options);
+
+// Extract the effective parameter vector from the preprocessed
+// problem and setup bits of the Minimizer::Options object that are
+// common to all Preprocessors.
+void SetupCommonMinimizerOptions(PreprocessedProblem* pp);
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_PREPROCESSOR_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/problem.cc b/extern/libmv/third_party/ceres/internal/ceres/problem.cc
index 674694dd506..bbfaa98769f 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/problem.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/problem.cc
@@ -251,6 +251,16 @@ void Problem::GetParameterBlocksForResidualBlock(
parameter_blocks);
}
+const CostFunction* Problem::GetCostFunctionForResidualBlock(
+ const ResidualBlockId residual_block) const {
+ return problem_impl_->GetCostFunctionForResidualBlock(residual_block);
+}
+
+const LossFunction* Problem::GetLossFunctionForResidualBlock(
+ const ResidualBlockId residual_block) const {
+ return problem_impl_->GetLossFunctionForResidualBlock(residual_block);
+}
+
void Problem::GetResidualBlocksForParameterBlock(
const double* values,
vector<ResidualBlockId>* residual_blocks) const {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc
index 7c86efb4921..67cac94d6ac 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.cc
@@ -823,6 +823,16 @@ void ProblemImpl::GetParameterBlocksForResidualBlock(
}
}
+const CostFunction* ProblemImpl::GetCostFunctionForResidualBlock(
+ const ResidualBlockId residual_block) const {
+ return residual_block->cost_function();
+}
+
+const LossFunction* ProblemImpl::GetLossFunctionForResidualBlock(
+ const ResidualBlockId residual_block) const {
+ return residual_block->loss_function();
+}
+
void ProblemImpl::GetResidualBlocksForParameterBlock(
const double* values,
vector<ResidualBlockId>* residual_blocks) const {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h
index 7b5547bd95a..3d84de83c5a 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/problem_impl.h
@@ -157,6 +157,11 @@ class ProblemImpl {
const ResidualBlockId residual_block,
vector<double*>* parameter_blocks) const;
+ const CostFunction* GetCostFunctionForResidualBlock(
+ const ResidualBlockId residual_block) const;
+ const LossFunction* GetLossFunctionForResidualBlock(
+ const ResidualBlockId residual_block) const;
+
void GetResidualBlocksForParameterBlock(
const double* values,
vector<ResidualBlockId>* residual_blocks) const;
diff --git a/extern/libmv/third_party/ceres/internal/ceres/program.cc b/extern/libmv/third_party/ceres/internal/ceres/program.cc
index 9e5c51bd696..1d0a1573e3b 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/program.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/program.cc
@@ -32,6 +32,7 @@
#include <map>
#include <vector>
+#include "ceres/array_utils.h"
#include "ceres/casts.h"
#include "ceres/compressed_row_sparse_matrix.h"
#include "ceres/cost_function.h"
@@ -44,6 +45,7 @@
#include "ceres/problem.h"
#include "ceres/residual_block.h"
#include "ceres/stl_util.h"
+#include "ceres/triplet_sparse_matrix.h"
namespace ceres {
namespace internal {
@@ -170,6 +172,259 @@ bool Program::IsValid() const {
return true;
}
+bool Program::ParameterBlocksAreFinite(string* message) const {
+ CHECK_NOTNULL(message);
+ for (int i = 0; i < parameter_blocks_.size(); ++i) {
+ const ParameterBlock* parameter_block = parameter_blocks_[i];
+ const double* array = parameter_block->user_state();
+ const int size = parameter_block->Size();
+ const int invalid_index = FindInvalidValue(size, array);
+ if (invalid_index != size) {
+ *message = StringPrintf(
+ "ParameterBlock: %p with size %d has at least one invalid value.\n"
+ "First invalid value is at index: %d.\n"
+ "Parameter block values: ",
+ array, size, invalid_index);
+ AppendArrayToString(size, array, message);
+ return false;
+ }
+ }
+ return true;
+}
+
+bool Program::IsBoundsConstrained() const {
+ for (int i = 0; i < parameter_blocks_.size(); ++i) {
+ const ParameterBlock* parameter_block = parameter_blocks_[i];
+ if (parameter_block->IsConstant()) {
+ continue;
+ }
+ const int size = parameter_block->Size();
+ for (int j = 0; j < size; ++j) {
+ const double lower_bound = parameter_block->LowerBoundForParameter(j);
+ const double upper_bound = parameter_block->UpperBoundForParameter(j);
+ if (lower_bound > -std::numeric_limits<double>::max() ||
+ upper_bound < std::numeric_limits<double>::max()) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+bool Program::IsFeasible(string* message) const {
+ CHECK_NOTNULL(message);
+ for (int i = 0; i < parameter_blocks_.size(); ++i) {
+ const ParameterBlock* parameter_block = parameter_blocks_[i];
+ const double* parameters = parameter_block->user_state();
+ const int size = parameter_block->Size();
+ if (parameter_block->IsConstant()) {
+ // Constant parameter blocks must start in the feasible region
+ // to ultimately produce a feasible solution, since Ceres cannot
+ // change them.
+ for (int j = 0; j < size; ++j) {
+ const double lower_bound = parameter_block->LowerBoundForParameter(j);
+ const double upper_bound = parameter_block->UpperBoundForParameter(j);
+ if (parameters[j] < lower_bound || parameters[j] > upper_bound) {
+ *message = StringPrintf(
+ "ParameterBlock: %p with size %d has at least one infeasible "
+ "value."
+ "\nFirst infeasible value is at index: %d."
+ "\nLower bound: %e, value: %e, upper bound: %e"
+ "\nParameter block values: ",
+ parameters, size, j, lower_bound, parameters[j], upper_bound);
+ AppendArrayToString(size, parameters, message);
+ return false;
+ }
+ }
+ } else {
+ // Variable parameter blocks must have non-empty feasible
+ // regions, otherwise there is no way to produce a feasible
+ // solution.
+ for (int j = 0; j < size; ++j) {
+ const double lower_bound = parameter_block->LowerBoundForParameter(j);
+ const double upper_bound = parameter_block->UpperBoundForParameter(j);
+ if (lower_bound >= upper_bound) {
+ *message = StringPrintf(
+ "ParameterBlock: %p with size %d has at least one infeasible "
+ "bound."
+ "\nFirst infeasible bound is at index: %d."
+ "\nLower bound: %e, upper bound: %e"
+ "\nParameter block values: ",
+ parameters, size, j, lower_bound, upper_bound);
+ AppendArrayToString(size, parameters, message);
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+Program* Program::CreateReducedProgram(vector<double*>* removed_parameter_blocks,
+ double* fixed_cost,
+ string* error) const {
+ CHECK_NOTNULL(removed_parameter_blocks);
+ CHECK_NOTNULL(fixed_cost);
+ CHECK_NOTNULL(error);
+
+ scoped_ptr<Program> reduced_program(new Program(*this));
+ if (!reduced_program->RemoveFixedBlocks(removed_parameter_blocks,
+ fixed_cost,
+ error)) {
+ return NULL;
+ }
+
+ reduced_program->SetParameterOffsetsAndIndex();
+ return reduced_program.release();
+}
+
+bool Program::RemoveFixedBlocks(vector<double*>* removed_parameter_blocks,
+ double* fixed_cost,
+ string* error) {
+ CHECK_NOTNULL(removed_parameter_blocks);
+ CHECK_NOTNULL(fixed_cost);
+ CHECK_NOTNULL(error);
+
+ scoped_array<double> residual_block_evaluate_scratch;
+ residual_block_evaluate_scratch.reset(
+ new double[MaxScratchDoublesNeededForEvaluate()]);
+ *fixed_cost = 0.0;
+
+ // Mark all the parameters as unused. Abuse the index member of the
+ // parameter blocks for the marking.
+ for (int i = 0; i < parameter_blocks_.size(); ++i) {
+ parameter_blocks_[i]->set_index(-1);
+ }
+
+ // Filter out residual that have all-constant parameters, and mark
+ // all the parameter blocks that appear in residuals.
+ int num_active_residual_blocks = 0;
+ for (int i = 0; i < residual_blocks_.size(); ++i) {
+ ResidualBlock* residual_block = residual_blocks_[i];
+ int num_parameter_blocks = residual_block->NumParameterBlocks();
+
+ // Determine if the residual block is fixed, and also mark varying
+ // parameters that appear in the residual block.
+ bool all_constant = true;
+ for (int k = 0; k < num_parameter_blocks; k++) {
+ ParameterBlock* parameter_block = residual_block->parameter_blocks()[k];
+ if (!parameter_block->IsConstant()) {
+ all_constant = false;
+ parameter_block->set_index(1);
+ }
+ }
+
+ if (!all_constant) {
+ residual_blocks_[num_active_residual_blocks++] = residual_block;
+ continue;
+ }
+
+ // The residual is constant and will be removed, so its cost is
+ // added to the variable fixed_cost.
+ double cost = 0.0;
+ if (!residual_block->Evaluate(true,
+ &cost,
+ NULL,
+ NULL,
+ residual_block_evaluate_scratch.get())) {
+ *error = StringPrintf("Evaluation of the residual %d failed during "
+ "removal of fixed residual blocks.", i);
+ return false;
+ }
+ *fixed_cost += cost;
+ }
+ residual_blocks_.resize(num_active_residual_blocks);
+
+ // Filter out unused or fixed parameter blocks.
+ int num_active_parameter_blocks = 0;
+ removed_parameter_blocks->clear();
+ for (int i = 0; i < parameter_blocks_.size(); ++i) {
+ ParameterBlock* parameter_block = parameter_blocks_[i];
+ if (parameter_block->index() == -1) {
+ removed_parameter_blocks->push_back(parameter_block->mutable_user_state());
+ } else {
+ parameter_blocks_[num_active_parameter_blocks++] = parameter_block;
+ }
+ }
+ parameter_blocks_.resize(num_active_parameter_blocks);
+
+ if (!(((NumResidualBlocks() == 0) &&
+ (NumParameterBlocks() == 0)) ||
+ ((NumResidualBlocks() != 0) &&
+ (NumParameterBlocks() != 0)))) {
+ *error = "Congratulations, you found a bug in Ceres. Please report it.";
+ return false;
+ }
+
+ return true;
+}
+
+bool Program::IsParameterBlockSetIndependent(const set<double*>& independent_set) const {
+ // Loop over each residual block and ensure that no two parameter
+ // blocks in the same residual block are part of
+ // parameter_block_ptrs as that would violate the assumption that it
+ // is an independent set in the Hessian matrix.
+ for (vector<ResidualBlock*>::const_iterator it = residual_blocks_.begin();
+ it != residual_blocks_.end();
+ ++it) {
+ ParameterBlock* const* parameter_blocks = (*it)->parameter_blocks();
+ const int num_parameter_blocks = (*it)->NumParameterBlocks();
+ int count = 0;
+ for (int i = 0; i < num_parameter_blocks; ++i) {
+ count += independent_set.count(
+ parameter_blocks[i]->mutable_user_state());
+ }
+ if (count > 1) {
+ return false;
+ }
+ }
+ return true;
+}
+
+TripletSparseMatrix* Program::CreateJacobianBlockSparsityTranspose() const {
+ // Matrix to store the block sparsity structure of the Jacobian.
+ TripletSparseMatrix* tsm =
+ new TripletSparseMatrix(NumParameterBlocks(),
+ NumResidualBlocks(),
+ 10 * NumResidualBlocks());
+ int num_nonzeros = 0;
+ int* rows = tsm->mutable_rows();
+ int* cols = tsm->mutable_cols();
+ double* values = tsm->mutable_values();
+
+ for (int c = 0; c < residual_blocks_.size(); ++c) {
+ const ResidualBlock* residual_block = residual_blocks_[c];
+ const int num_parameter_blocks = residual_block->NumParameterBlocks();
+ ParameterBlock* const* parameter_blocks =
+ residual_block->parameter_blocks();
+
+ for (int j = 0; j < num_parameter_blocks; ++j) {
+ if (parameter_blocks[j]->IsConstant()) {
+ continue;
+ }
+
+ // Re-size the matrix if needed.
+ if (num_nonzeros >= tsm->max_num_nonzeros()) {
+ tsm->set_num_nonzeros(num_nonzeros);
+ tsm->Reserve(2 * num_nonzeros);
+ rows = tsm->mutable_rows();
+ cols = tsm->mutable_cols();
+ values = tsm->mutable_values();
+ }
+
+ const int r = parameter_blocks[j]->index();
+ rows[num_nonzeros] = r;
+ cols[num_nonzeros] = c;
+ values[num_nonzeros] = 1.0;
+ ++num_nonzeros;
+ }
+ }
+
+ tsm->set_num_nonzeros(num_nonzeros);
+ return tsm;
+}
+
int Program::NumResidualBlocks() const {
return residual_blocks_.size();
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/program.h b/extern/libmv/third_party/ceres/internal/ceres/program.h
index 4288f609cf8..c7b22c4d244 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/program.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/program.h
@@ -31,6 +31,7 @@
#ifndef CERES_INTERNAL_PROGRAM_H_
#define CERES_INTERNAL_PROGRAM_H_
+#include <set>
#include <string>
#include <vector>
#include "ceres/internal/port.h"
@@ -41,6 +42,7 @@ namespace internal {
class ParameterBlock;
class ProblemImpl;
class ResidualBlock;
+class TripletSparseMatrix;
// A nonlinear least squares optimization problem. This is different from the
// similarly-named "Problem" object, which offers a mutation interface for
@@ -103,6 +105,47 @@ class Program {
// offsets) are correct.
bool IsValid() const;
+ bool ParameterBlocksAreFinite(string* message) const;
+
+ // Returns true if the program has any non-constant parameter blocks
+ // which have non-trivial bounds constraints.
+ bool IsBoundsConstrained() const;
+
+ // Returns false, if the program has any constant parameter blocks
+ // which are not feasible, or any variable parameter blocks which
+ // have a lower bound greater than or equal to the upper bound.
+ bool IsFeasible(string* message) const;
+
+ // Loop over each residual block and ensure that no two parameter
+ // blocks in the same residual block are part of
+ // parameter_blocks as that would violate the assumption that it
+ // is an independent set in the Hessian matrix.
+ bool IsParameterBlockSetIndependent(const set<double*>& independent_set) const;
+
+ // Create a TripletSparseMatrix which contains the zero-one
+ // structure corresponding to the block sparsity of the transpose of
+ // the Jacobian matrix.
+ //
+ // Caller owns the result.
+ TripletSparseMatrix* CreateJacobianBlockSparsityTranspose() const;
+
+ // Create a copy of this program and removes constant parameter
+ // blocks and residual blocks with no varying parameter blocks while
+ // preserving their relative order.
+ //
+ // removed_parameter_blocks on exit will contain the list of
+ // parameter blocks that were removed.
+ //
+ // fixed_cost will be equal to the sum of the costs of the residual
+ // blocks that were removed.
+ //
+ // If there was a problem, then the function will return a NULL
+ // pointer and error will contain a human readable description of
+ // the problem.
+ Program* CreateReducedProgram(vector<double*>* removed_parameter_blocks,
+ double* fixed_cost,
+ string* error) const;
+
// See problem.h for what these do.
int NumParameterBlocks() const;
int NumParameters() const;
@@ -120,6 +163,21 @@ class Program {
string ToString() const;
private:
+ // Remove constant parameter blocks and residual blocks with no
+ // varying parameter blocks while preserving their relative order.
+ //
+ // removed_parameter_blocks on exit will contain the list of
+ // parameter blocks that were removed.
+ //
+ // fixed_cost will be equal to the sum of the costs of the residual
+ // blocks that were removed.
+ //
+ // If there was a problem, then the function will return false and
+ // error will contain a human readable description of the problem.
+ bool RemoveFixedBlocks(vector<double*>* removed_parameter_blocks,
+ double* fixed_cost,
+ string* message);
+
// The Program does not own the ParameterBlock or ResidualBlock objects.
vector<ParameterBlock*> parameter_blocks_;
vector<ResidualBlock*> residual_blocks_;
diff --git a/extern/libmv/third_party/ceres/internal/ceres/reorder_program.cc b/extern/libmv/third_party/ceres/internal/ceres/reorder_program.cc
new file mode 100644
index 00000000000..aa3d4cec396
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/reorder_program.cc
@@ -0,0 +1,578 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#include "ceres/reorder_program.h"
+
+#include <algorithm>
+#include <numeric>
+#include <vector>
+
+#include "ceres/cxsparse.h"
+#include "ceres/internal/port.h"
+#include "ceres/ordered_groups.h"
+#include "ceres/parameter_block.h"
+#include "ceres/parameter_block_ordering.h"
+#include "ceres/problem_impl.h"
+#include "ceres/program.h"
+#include "ceres/residual_block.h"
+#include "ceres/solver.h"
+#include "ceres/suitesparse.h"
+#include "ceres/triplet_sparse_matrix.h"
+#include "ceres/types.h"
+#include "Eigen/SparseCore"
+
+#ifdef CERES_USE_EIGEN_SPARSE
+#include "Eigen/OrderingMethods"
+#endif
+
+#include "glog/logging.h"
+
+namespace ceres {
+namespace internal {
+namespace {
+
+// Find the minimum index of any parameter block to the given
+// residual. Parameter blocks that have indices greater than
+// size_of_first_elimination_group are considered to have an index
+// equal to size_of_first_elimination_group.
+static int MinParameterBlock(const ResidualBlock* residual_block,
+ int size_of_first_elimination_group) {
+ int min_parameter_block_position = size_of_first_elimination_group;
+ for (int i = 0; i < residual_block->NumParameterBlocks(); ++i) {
+ ParameterBlock* parameter_block = residual_block->parameter_blocks()[i];
+ if (!parameter_block->IsConstant()) {
+ CHECK_NE(parameter_block->index(), -1)
+ << "Did you forget to call Program::SetParameterOffsetsAndIndex()? "
+ << "This is a Ceres bug; please contact the developers!";
+ min_parameter_block_position = std::min(parameter_block->index(),
+ min_parameter_block_position);
+ }
+ }
+ return min_parameter_block_position;
+}
+
+#if EIGEN_VERSION_AT_LEAST(3, 2, 2) && defined(CERES_USE_EIGEN_SPARSE)
+Eigen::SparseMatrix<int> CreateBlockJacobian(
+ const TripletSparseMatrix& block_jacobian_transpose) {
+ typedef Eigen::SparseMatrix<int> SparseMatrix;
+ typedef Eigen::Triplet<int> Triplet;
+
+ const int* rows = block_jacobian_transpose.rows();
+ const int* cols = block_jacobian_transpose.cols();
+ int num_nonzeros = block_jacobian_transpose.num_nonzeros();
+ std::vector<Triplet> triplets;
+ triplets.reserve(num_nonzeros);
+ for (int i = 0; i < num_nonzeros; ++i) {
+ triplets.push_back(Triplet(cols[i], rows[i], 1));
+ }
+
+ SparseMatrix block_jacobian(block_jacobian_transpose.num_cols(),
+ block_jacobian_transpose.num_rows());
+ block_jacobian.setFromTriplets(triplets.begin(), triplets.end());
+ return block_jacobian;
+}
+#endif
+
+void OrderingForSparseNormalCholeskyUsingSuiteSparse(
+ const TripletSparseMatrix& tsm_block_jacobian_transpose,
+ const vector<ParameterBlock*>& parameter_blocks,
+ const ParameterBlockOrdering& parameter_block_ordering,
+ int* ordering) {
+#ifdef CERES_NO_SUITESPARSE
+ LOG(FATAL) << "Congratulations, you found a Ceres bug! "
+ << "Please report this error to the developers.";
+#else
+ SuiteSparse ss;
+ cholmod_sparse* block_jacobian_transpose =
+ ss.CreateSparseMatrix(
+ const_cast<TripletSparseMatrix*>(&tsm_block_jacobian_transpose));
+
+ // No CAMD or the user did not supply a useful ordering, then just
+ // use regular AMD.
+ if (parameter_block_ordering.NumGroups() <= 1 ||
+ !SuiteSparse::IsConstrainedApproximateMinimumDegreeOrderingAvailable()) {
+ ss.ApproximateMinimumDegreeOrdering(block_jacobian_transpose, &ordering[0]);
+ } else {
+ vector<int> constraints;
+ for (int i = 0; i < parameter_blocks.size(); ++i) {
+ constraints.push_back(
+ parameter_block_ordering.GroupId(
+ parameter_blocks[i]->mutable_user_state()));
+ }
+ ss.ConstrainedApproximateMinimumDegreeOrdering(block_jacobian_transpose,
+ &constraints[0],
+ ordering);
+ }
+
+ ss.Free(block_jacobian_transpose);
+#endif // CERES_NO_SUITESPARSE
+}
+
+void OrderingForSparseNormalCholeskyUsingCXSparse(
+ const TripletSparseMatrix& tsm_block_jacobian_transpose,
+ int* ordering) {
+#ifdef CERES_NO_CXSPARSE
+ LOG(FATAL) << "Congratulations, you found a Ceres bug! "
+ << "Please report this error to the developers.";
+#else // CERES_NO_CXSPARSE
+ // CXSparse works with J'J instead of J'. So compute the block
+ // sparsity for J'J and compute an approximate minimum degree
+ // ordering.
+ CXSparse cxsparse;
+ cs_di* block_jacobian_transpose;
+ block_jacobian_transpose =
+ cxsparse.CreateSparseMatrix(
+ const_cast<TripletSparseMatrix*>(&tsm_block_jacobian_transpose));
+ cs_di* block_jacobian = cxsparse.TransposeMatrix(block_jacobian_transpose);
+ cs_di* block_hessian =
+ cxsparse.MatrixMatrixMultiply(block_jacobian_transpose, block_jacobian);
+ cxsparse.Free(block_jacobian);
+ cxsparse.Free(block_jacobian_transpose);
+
+ cxsparse.ApproximateMinimumDegreeOrdering(block_hessian, ordering);
+ cxsparse.Free(block_hessian);
+#endif // CERES_NO_CXSPARSE
+}
+
+
+#if EIGEN_VERSION_AT_LEAST(3, 2, 2)
+void OrderingForSparseNormalCholeskyUsingEigenSparse(
+ const TripletSparseMatrix& tsm_block_jacobian_transpose,
+ int* ordering) {
+#ifndef CERES_USE_EIGEN_SPARSE
+ LOG(FATAL) <<
+ "SPARSE_NORMAL_CHOLESKY cannot be used with EIGEN_SPARSE "
+ "because Ceres was not built with support for "
+ "Eigen's SimplicialLDLT decomposition. "
+ "This requires enabling building with -DEIGENSPARSE=ON.";
+#else
+
+ // This conversion from a TripletSparseMatrix to a Eigen::Triplet
+ // matrix is unfortunate, but unavoidable for now. It is not a
+ // significant performance penalty in the grand scheme of
+ // things. The right thing to do here would be to get a compressed
+ // row sparse matrix representation of the jacobian and go from
+ // there. But that is a project for another day.
+ typedef Eigen::SparseMatrix<int> SparseMatrix;
+
+ const SparseMatrix block_jacobian =
+ CreateBlockJacobian(tsm_block_jacobian_transpose);
+ const SparseMatrix block_hessian =
+ block_jacobian.transpose() * block_jacobian;
+
+ Eigen::AMDOrdering<int> amd_ordering;
+ Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic, int> perm;
+ amd_ordering(block_hessian, perm);
+ for (int i = 0; i < block_hessian.rows(); ++i) {
+ ordering[i] = perm.indices()[i];
+ }
+#endif // CERES_USE_EIGEN_SPARSE
+}
+#endif
+
+} // namespace
+
+bool ApplyOrdering(const ProblemImpl::ParameterMap& parameter_map,
+ const ParameterBlockOrdering& ordering,
+ Program* program,
+ string* error) {
+ const int num_parameter_blocks = program->NumParameterBlocks();
+ if (ordering.NumElements() != num_parameter_blocks) {
+ *error = StringPrintf("User specified ordering does not have the same "
+ "number of parameters as the problem. The problem"
+ "has %d blocks while the ordering has %d blocks.",
+ num_parameter_blocks,
+ ordering.NumElements());
+ return false;
+ }
+
+ vector<ParameterBlock*>* parameter_blocks =
+ program->mutable_parameter_blocks();
+ parameter_blocks->clear();
+
+ const map<int, set<double*> >& groups =
+ ordering.group_to_elements();
+
+ for (map<int, set<double*> >::const_iterator group_it = groups.begin();
+ group_it != groups.end();
+ ++group_it) {
+ const set<double*>& group = group_it->second;
+ for (set<double*>::const_iterator parameter_block_ptr_it = group.begin();
+ parameter_block_ptr_it != group.end();
+ ++parameter_block_ptr_it) {
+ ProblemImpl::ParameterMap::const_iterator parameter_block_it =
+ parameter_map.find(*parameter_block_ptr_it);
+ if (parameter_block_it == parameter_map.end()) {
+ *error = StringPrintf("User specified ordering contains a pointer "
+ "to a double that is not a parameter block in "
+ "the problem. The invalid double is in group: %d",
+ group_it->first);
+ return false;
+ }
+ parameter_blocks->push_back(parameter_block_it->second);
+ }
+ }
+ return true;
+}
+
+bool LexicographicallyOrderResidualBlocks(
+ const int size_of_first_elimination_group,
+ Program* program,
+ string* error) {
+ CHECK_GE(size_of_first_elimination_group, 1)
+ << "Congratulations, you found a Ceres bug! Please report this error "
+ << "to the developers.";
+
+ // Create a histogram of the number of residuals for each E block. There is an
+ // extra bucket at the end to catch all non-eliminated F blocks.
+ vector<int> residual_blocks_per_e_block(size_of_first_elimination_group + 1);
+ vector<ResidualBlock*>* residual_blocks = program->mutable_residual_blocks();
+ vector<int> min_position_per_residual(residual_blocks->size());
+ for (int i = 0; i < residual_blocks->size(); ++i) {
+ ResidualBlock* residual_block = (*residual_blocks)[i];
+ int position = MinParameterBlock(residual_block,
+ size_of_first_elimination_group);
+ min_position_per_residual[i] = position;
+ DCHECK_LE(position, size_of_first_elimination_group);
+ residual_blocks_per_e_block[position]++;
+ }
+
+ // Run a cumulative sum on the histogram, to obtain offsets to the start of
+ // each histogram bucket (where each bucket is for the residuals for that
+ // E-block).
+ vector<int> offsets(size_of_first_elimination_group + 1);
+ std::partial_sum(residual_blocks_per_e_block.begin(),
+ residual_blocks_per_e_block.end(),
+ offsets.begin());
+ CHECK_EQ(offsets.back(), residual_blocks->size())
+ << "Congratulations, you found a Ceres bug! Please report this error "
+ << "to the developers.";
+
+ CHECK(find(residual_blocks_per_e_block.begin(),
+ residual_blocks_per_e_block.end() - 1, 0) !=
+ residual_blocks_per_e_block.end())
+ << "Congratulations, you found a Ceres bug! Please report this error "
+ << "to the developers.";
+
+ // Fill in each bucket with the residual blocks for its corresponding E block.
+ // Each bucket is individually filled from the back of the bucket to the front
+ // of the bucket. The filling order among the buckets is dictated by the
+ // residual blocks. This loop uses the offsets as counters; subtracting one
+ // from each offset as a residual block is placed in the bucket. When the
+ // filling is finished, the offset pointerts should have shifted down one
+ // entry (this is verified below).
+ vector<ResidualBlock*> reordered_residual_blocks(
+ (*residual_blocks).size(), static_cast<ResidualBlock*>(NULL));
+ for (int i = 0; i < residual_blocks->size(); ++i) {
+ int bucket = min_position_per_residual[i];
+
+ // Decrement the cursor, which should now point at the next empty position.
+ offsets[bucket]--;
+
+ // Sanity.
+ CHECK(reordered_residual_blocks[offsets[bucket]] == NULL)
+ << "Congratulations, you found a Ceres bug! Please report this error "
+ << "to the developers.";
+
+ reordered_residual_blocks[offsets[bucket]] = (*residual_blocks)[i];
+ }
+
+ // Sanity check #1: The difference in bucket offsets should match the
+ // histogram sizes.
+ for (int i = 0; i < size_of_first_elimination_group; ++i) {
+ CHECK_EQ(residual_blocks_per_e_block[i], offsets[i + 1] - offsets[i])
+ << "Congratulations, you found a Ceres bug! Please report this error "
+ << "to the developers.";
+ }
+ // Sanity check #2: No NULL's left behind.
+ for (int i = 0; i < reordered_residual_blocks.size(); ++i) {
+ CHECK(reordered_residual_blocks[i] != NULL)
+ << "Congratulations, you found a Ceres bug! Please report this error "
+ << "to the developers.";
+ }
+
+ // Now that the residuals are collected by E block, swap them in place.
+ swap(*program->mutable_residual_blocks(), reordered_residual_blocks);
+ return true;
+}
+
+// Pre-order the columns corresponding to the schur complement if
+// possible.
+void MaybeReorderSchurComplementColumnsUsingSuiteSparse(
+ const ParameterBlockOrdering& parameter_block_ordering,
+ Program* program) {
+#ifndef CERES_NO_SUITESPARSE
+ SuiteSparse ss;
+ if (!SuiteSparse::IsConstrainedApproximateMinimumDegreeOrderingAvailable()) {
+ return;
+ }
+
+ vector<int> constraints;
+ vector<ParameterBlock*>& parameter_blocks =
+ *(program->mutable_parameter_blocks());
+
+ for (int i = 0; i < parameter_blocks.size(); ++i) {
+ constraints.push_back(
+ parameter_block_ordering.GroupId(
+ parameter_blocks[i]->mutable_user_state()));
+ }
+
+ // Renumber the entries of constraints to be contiguous integers
+ // as camd requires that the group ids be in the range [0,
+ // parameter_blocks.size() - 1].
+ MapValuesToContiguousRange(constraints.size(), &constraints[0]);
+
+ // Compute a block sparse presentation of J'.
+ scoped_ptr<TripletSparseMatrix> tsm_block_jacobian_transpose(
+ program->CreateJacobianBlockSparsityTranspose());
+
+ cholmod_sparse* block_jacobian_transpose =
+ ss.CreateSparseMatrix(tsm_block_jacobian_transpose.get());
+
+ vector<int> ordering(parameter_blocks.size(), 0);
+ ss.ConstrainedApproximateMinimumDegreeOrdering(block_jacobian_transpose,
+ &constraints[0],
+ &ordering[0]);
+ ss.Free(block_jacobian_transpose);
+
+ const vector<ParameterBlock*> parameter_blocks_copy(parameter_blocks);
+ for (int i = 0; i < program->NumParameterBlocks(); ++i) {
+ parameter_blocks[i] = parameter_blocks_copy[ordering[i]];
+ }
+
+ program->SetParameterOffsetsAndIndex();
+#endif
+}
+
+void MaybeReorderSchurComplementColumnsUsingEigen(
+ const int size_of_first_elimination_group,
+ const ProblemImpl::ParameterMap& parameter_map,
+ Program* program) {
+#if !EIGEN_VERSION_AT_LEAST(3, 2, 2) || !defined(CERES_USE_EIGEN_SPARSE)
+ return;
+#else
+
+ scoped_ptr<TripletSparseMatrix> tsm_block_jacobian_transpose(
+ program->CreateJacobianBlockSparsityTranspose());
+
+ typedef Eigen::SparseMatrix<int> SparseMatrix;
+ const SparseMatrix block_jacobian =
+ CreateBlockJacobian(*tsm_block_jacobian_transpose);
+ const int num_rows = block_jacobian.rows();
+ const int num_cols = block_jacobian.cols();
+
+ // Vertically partition the jacobian in parameter blocks of type E
+ // and F.
+ const SparseMatrix E =
+ block_jacobian.block(0,
+ 0,
+ num_rows,
+ size_of_first_elimination_group);
+ const SparseMatrix F =
+ block_jacobian.block(0,
+ size_of_first_elimination_group,
+ num_rows,
+ num_cols - size_of_first_elimination_group);
+
+ // Block sparsity pattern of the schur complement.
+ const SparseMatrix block_schur_complement =
+ F.transpose() * F - F.transpose() * E * E.transpose() * F;
+
+ Eigen::AMDOrdering<int> amd_ordering;
+ Eigen::PermutationMatrix<Eigen::Dynamic, Eigen::Dynamic, int> perm;
+ amd_ordering(block_schur_complement, perm);
+
+ const vector<ParameterBlock*>& parameter_blocks = program->parameter_blocks();
+ vector<ParameterBlock*> ordering(num_cols);
+
+ // The ordering of the first size_of_first_elimination_group does
+ // not matter, so we preserve the existing ordering.
+ for (int i = 0; i < size_of_first_elimination_group; ++i) {
+ ordering[i] = parameter_blocks[i];
+ }
+
+ // For the rest of the blocks, use the ordering computed using AMD.
+ for (int i = 0; i < block_schur_complement.cols(); ++i) {
+ ordering[size_of_first_elimination_group + i] =
+ parameter_blocks[size_of_first_elimination_group + perm.indices()[i]];
+ }
+
+ swap(*program->mutable_parameter_blocks(), ordering);
+ program->SetParameterOffsetsAndIndex();
+#endif
+}
+
+bool ReorderProgramForSchurTypeLinearSolver(
+ const LinearSolverType linear_solver_type,
+ const SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
+ const ProblemImpl::ParameterMap& parameter_map,
+ ParameterBlockOrdering* parameter_block_ordering,
+ Program* program,
+ string* error) {
+ if (parameter_block_ordering->NumElements() !=
+ program->NumParameterBlocks()) {
+ *error = StringPrintf(
+ "The program has %d parameter blocks, but the parameter block "
+ "ordering has %d parameter blocks.",
+ program->NumParameterBlocks(),
+ parameter_block_ordering->NumElements());
+ return false;
+ }
+
+ if (parameter_block_ordering->NumGroups() == 1) {
+ // If the user supplied an parameter_block_ordering with just one
+ // group, it is equivalent to the user supplying NULL as an
+ // parameter_block_ordering. Ceres is completely free to choose the
+ // parameter block ordering as it sees fit. For Schur type solvers,
+ // this means that the user wishes for Ceres to identify the
+ // e_blocks, which we do by computing a maximal independent set.
+ vector<ParameterBlock*> schur_ordering;
+ const int size_of_first_elimination_group =
+ ComputeStableSchurOrdering(*program, &schur_ordering);
+
+ CHECK_EQ(schur_ordering.size(), program->NumParameterBlocks())
+ << "Congratulations, you found a Ceres bug! Please report this error "
+ << "to the developers.";
+
+ // Update the parameter_block_ordering object.
+ for (int i = 0; i < schur_ordering.size(); ++i) {
+ double* parameter_block = schur_ordering[i]->mutable_user_state();
+ const int group_id = (i < size_of_first_elimination_group) ? 0 : 1;
+ parameter_block_ordering->AddElementToGroup(parameter_block, group_id);
+ }
+
+ // We could call ApplyOrdering but this is cheaper and
+ // simpler.
+ swap(*program->mutable_parameter_blocks(), schur_ordering);
+ } else {
+ // The user provided an ordering with more than one elimination
+ // group.
+
+ // Verify that the first elimination group is an independent set.
+ const set<double*>& first_elimination_group =
+ parameter_block_ordering
+ ->group_to_elements()
+ .begin()
+ ->second;
+ if (!program->IsParameterBlockSetIndependent(first_elimination_group)) {
+ *error =
+ StringPrintf("The first elimination group in the parameter block "
+ "ordering of size %zd is not an independent set",
+ first_elimination_group.size());
+ return false;
+ }
+
+ if (!ApplyOrdering(parameter_map,
+ *parameter_block_ordering,
+ program,
+ error)) {
+ return false;
+ }
+ }
+
+ program->SetParameterOffsetsAndIndex();
+
+ const int size_of_first_elimination_group =
+ parameter_block_ordering->group_to_elements().begin()->second.size();
+
+ if (linear_solver_type == SPARSE_SCHUR) {
+ if (sparse_linear_algebra_library_type == SUITE_SPARSE) {
+ MaybeReorderSchurComplementColumnsUsingSuiteSparse(
+ *parameter_block_ordering,
+ program);
+ } else if (sparse_linear_algebra_library_type == EIGEN_SPARSE) {
+ MaybeReorderSchurComplementColumnsUsingEigen(
+ size_of_first_elimination_group,
+ parameter_map,
+ program);
+ }
+ }
+
+ // Schur type solvers also require that their residual blocks be
+ // lexicographically ordered.
+ if (!LexicographicallyOrderResidualBlocks(size_of_first_elimination_group,
+ program,
+ error)) {
+ return false;
+ }
+
+ return true;
+}
+
+bool ReorderProgramForSparseNormalCholesky(
+ const SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
+ const ParameterBlockOrdering& parameter_block_ordering,
+ Program* program,
+ string* error) {
+ // Compute a block sparse presentation of J'.
+ scoped_ptr<TripletSparseMatrix> tsm_block_jacobian_transpose(
+ program->CreateJacobianBlockSparsityTranspose());
+
+ vector<int> ordering(program->NumParameterBlocks(), 0);
+ vector<ParameterBlock*>& parameter_blocks =
+ *(program->mutable_parameter_blocks());
+
+ if (sparse_linear_algebra_library_type == SUITE_SPARSE) {
+ OrderingForSparseNormalCholeskyUsingSuiteSparse(
+ *tsm_block_jacobian_transpose,
+ parameter_blocks,
+ parameter_block_ordering,
+ &ordering[0]);
+ } else if (sparse_linear_algebra_library_type == CX_SPARSE) {
+ OrderingForSparseNormalCholeskyUsingCXSparse(
+ *tsm_block_jacobian_transpose,
+ &ordering[0]);
+ } else if (sparse_linear_algebra_library_type == EIGEN_SPARSE) {
+#if EIGEN_VERSION_AT_LEAST(3, 2, 2)
+ OrderingForSparseNormalCholeskyUsingEigenSparse(
+ *tsm_block_jacobian_transpose,
+ &ordering[0]);
+#else
+ // For Eigen versions less than 3.2.2, there is nothing to do as
+ // older versions of Eigen do not expose a method for doing
+ // symbolic analysis on pre-ordered matrices, so a block
+ // pre-ordering is a bit pointless.
+
+ return true;
+#endif
+ }
+
+ // Apply ordering.
+ const vector<ParameterBlock*> parameter_blocks_copy(parameter_blocks);
+ for (int i = 0; i < program->NumParameterBlocks(); ++i) {
+ parameter_blocks[i] = parameter_blocks_copy[ordering[i]];
+ }
+
+ program->SetParameterOffsetsAndIndex();
+ return true;
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/reorder_program.h b/extern/libmv/third_party/ceres/internal/ceres/reorder_program.h
new file mode 100644
index 00000000000..0474c1fb912
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/reorder_program.h
@@ -0,0 +1,101 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#ifndef CERES_INTERNAL_REORDER_PROGRAM_H_
+#define CERES_INTERNAL_REORDER_PROGRAM_H_
+
+#include <string>
+#include "ceres/internal/port.h"
+#include "ceres/parameter_block_ordering.h"
+#include "ceres/problem_impl.h"
+#include "ceres/types.h"
+
+namespace ceres {
+namespace internal {
+
+class Program;
+
+// Reorder the parameter blocks in program using the ordering
+bool ApplyOrdering(const ProblemImpl::ParameterMap& parameter_map,
+ const ParameterBlockOrdering& ordering,
+ Program* program,
+ string* error);
+
+// Reorder the residuals for program, if necessary, so that the residuals
+// involving each E block occur together. This is a necessary condition for the
+// Schur eliminator, which works on these "row blocks" in the jacobian.
+bool LexicographicallyOrderResidualBlocks(int size_of_first_elimination_group,
+ Program* program,
+ string* error);
+
+// Schur type solvers require that all parameter blocks eliminated
+// by the Schur eliminator occur before others and the residuals be
+// sorted in lexicographic order of their parameter blocks.
+//
+// If the parameter_block_ordering only contains one elimination
+// group then a maximal independent set is computed and used as the
+// first elimination group, otherwise the user's ordering is used.
+//
+// If the linear solver type is SPARSE_SCHUR and support for
+// constrained fill-reducing ordering is available in the sparse
+// linear algebra library (SuiteSparse version >= 4.2.0) then
+// columns of the schur complement matrix are ordered to reduce the
+// fill-in the Cholesky factorization.
+//
+// Upon return, ordering contains the parameter block ordering that
+// was used to order the program.
+bool ReorderProgramForSchurTypeLinearSolver(
+ LinearSolverType linear_solver_type,
+ SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
+ const ProblemImpl::ParameterMap& parameter_map,
+ ParameterBlockOrdering* parameter_block_ordering,
+ Program* program,
+ string* error);
+
+// Sparse cholesky factorization routines when doing the sparse
+// cholesky factorization of the Jacobian matrix, reorders its
+// columns to reduce the fill-in. Compute this permutation and
+// re-order the parameter blocks.
+//
+// When using SuiteSparse, if the parameter_block_ordering contains
+// more than one elimination group and support for constrained
+// fill-reducing ordering is available in the sparse linear algebra
+// library (SuiteSparse version >= 4.2.0) then the fill reducing
+// ordering will take it into account, otherwise it will be ignored.
+bool ReorderProgramForSparseNormalCholesky(
+ SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
+ const ParameterBlockOrdering& parameter_block_ordering,
+ Program* program,
+ string* error);
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_REORDER_PROGRAM_
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 d3eef5d4328..33f812b8c96 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
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2014 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -28,21 +28,22 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
+#include "ceres/internal/port.h"
+
#include <algorithm>
#include <ctime>
#include <set>
#include <vector>
-#include "Eigen/Dense"
#include "ceres/block_random_access_dense_matrix.h"
#include "ceres/block_random_access_matrix.h"
#include "ceres/block_random_access_sparse_matrix.h"
#include "ceres/block_sparse_matrix.h"
#include "ceres/block_structure.h"
+#include "ceres/conjugate_gradients_solver.h"
#include "ceres/cxsparse.h"
#include "ceres/detect_structure.h"
#include "ceres/internal/eigen.h"
-#include "ceres/internal/port.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/lapack.h"
#include "ceres/linear_solver.h"
@@ -51,9 +52,66 @@
#include "ceres/triplet_sparse_matrix.h"
#include "ceres/types.h"
#include "ceres/wall_time.h"
+#include "Eigen/Dense"
+#include "Eigen/SparseCore"
namespace ceres {
namespace internal {
+namespace {
+
+class BlockRandomAccessSparseMatrixAdapter : public LinearOperator {
+ public:
+ explicit BlockRandomAccessSparseMatrixAdapter(
+ const BlockRandomAccessSparseMatrix& m)
+ : m_(m) {
+ }
+
+ virtual ~BlockRandomAccessSparseMatrixAdapter() {}
+
+ // y = y + Ax;
+ virtual void RightMultiply(const double* x, double* y) const {
+ m_.SymmetricRightMultiply(x, y);
+ }
+
+ // y = y + A'x;
+ virtual void LeftMultiply(const double* x, double* y) const {
+ m_.SymmetricRightMultiply(x, y);
+ }
+
+ virtual int num_rows() const { return m_.num_rows(); }
+ virtual int num_cols() const { return m_.num_rows(); }
+
+ private:
+ const BlockRandomAccessSparseMatrix& m_;
+};
+
+class BlockRandomAccessDiagonalMatrixAdapter : public LinearOperator {
+ public:
+ explicit BlockRandomAccessDiagonalMatrixAdapter(
+ const BlockRandomAccessDiagonalMatrix& m)
+ : m_(m) {
+ }
+
+ virtual ~BlockRandomAccessDiagonalMatrixAdapter() {}
+
+ // y = y + Ax;
+ virtual void RightMultiply(const double* x, double* y) const {
+ m_.RightMultiply(x, y);
+ }
+
+ // y = y + A'x;
+ virtual void LeftMultiply(const double* x, double* y) const {
+ m_.RightMultiply(x, y);
+ }
+
+ virtual int num_rows() const { return m_.num_rows(); }
+ virtual int num_cols() const { return m_.num_rows(); }
+
+ private:
+ const BlockRandomAccessDiagonalMatrix& m_;
+};
+
+} // namespace
LinearSolver::Summary SchurComplementSolver::SolveImpl(
BlockSparseMatrix* A,
@@ -80,7 +138,7 @@ LinearSolver::Summary SchurComplementSolver::SolveImpl(
double* reduced_solution = x + A->num_cols() - lhs_->num_cols();
const LinearSolver::Summary summary =
- SolveReducedLinearSystem(reduced_solution);
+ SolveReducedLinearSystem(per_solve_options, reduced_solution);
event_logger.AddEvent("ReducedSolve");
if (summary.termination_type == LINEAR_SOLVER_SUCCESS) {
@@ -113,7 +171,9 @@ void DenseSchurComplementSolver::InitStorage(
// BlockRandomAccessDenseMatrix. The linear system is solved using
// Eigen's Cholesky factorization.
LinearSolver::Summary
-DenseSchurComplementSolver::SolveReducedLinearSystem(double* solution) {
+DenseSchurComplementSolver::SolveReducedLinearSystem(
+ const LinearSolver::PerSolveOptions& per_solve_options,
+ double* solution) {
LinearSolver::Summary summary;
summary.num_iterations = 0;
summary.termination_type = LINEAR_SOLVER_SUCCESS;
@@ -138,7 +198,8 @@ DenseSchurComplementSolver::SolveReducedLinearSystem(double* solution) {
.llt();
if (llt.info() != Eigen::Success) {
summary.termination_type = LINEAR_SOLVER_FAILURE;
- summary.message = "Eigen LLT decomposition failed.";
+ summary.message =
+ "Eigen failure. Unable to perform dense Cholesky factorization.";
return summary;
}
@@ -155,8 +216,6 @@ DenseSchurComplementSolver::SolveReducedLinearSystem(double* solution) {
return summary;
}
-#if !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARE)
-
SparseSchurComplementSolver::SparseSchurComplementSolver(
const LinearSolver::Options& options)
: SchurComplementSolver(options),
@@ -165,19 +224,15 @@ SparseSchurComplementSolver::SparseSchurComplementSolver(
}
SparseSchurComplementSolver::~SparseSchurComplementSolver() {
-#ifndef CERES_NO_SUITESPARSE
if (factor_ != NULL) {
ss_.Free(factor_);
factor_ = NULL;
}
-#endif // CERES_NO_SUITESPARSE
-#ifndef CERES_NO_CXSPARSE
if (cxsparse_factor_ != NULL) {
cxsparse_.Free(cxsparse_factor_);
cxsparse_factor_ = NULL;
}
-#endif // CERES_NO_CXSPARSE
}
// Determine the non-zero blocks in the Schur Complement matrix, and
@@ -252,12 +307,25 @@ void SparseSchurComplementSolver::InitStorage(
}
LinearSolver::Summary
-SparseSchurComplementSolver::SolveReducedLinearSystem(double* solution) {
+SparseSchurComplementSolver::SolveReducedLinearSystem(
+ const LinearSolver::PerSolveOptions& per_solve_options,
+ double* solution) {
+ if (options().type == ITERATIVE_SCHUR) {
+ CHECK(options().use_explicit_schur_complement);
+ return SolveReducedLinearSystemUsingConjugateGradients(per_solve_options,
+ solution);
+ }
+
switch (options().sparse_linear_algebra_library_type) {
case SUITE_SPARSE:
- return SolveReducedLinearSystemUsingSuiteSparse(solution);
+ return SolveReducedLinearSystemUsingSuiteSparse(per_solve_options,
+ solution);
case CX_SPARSE:
- return SolveReducedLinearSystemUsingCXSparse(solution);
+ return SolveReducedLinearSystemUsingCXSparse(per_solve_options,
+ solution);
+ case EIGEN_SPARSE:
+ return SolveReducedLinearSystemUsingEigen(per_solve_options,
+ solution);
default:
LOG(FATAL) << "Unknown sparse linear algebra library : "
<< options().sparse_linear_algebra_library_type;
@@ -266,13 +334,24 @@ SparseSchurComplementSolver::SolveReducedLinearSystem(double* solution) {
return LinearSolver::Summary();
}
-#ifndef CERES_NO_SUITESPARSE
// Solve the system Sx = r, assuming that the matrix S is stored in a
// BlockRandomAccessSparseMatrix. The linear system is solved using
// CHOLMOD's sparse cholesky factorization routines.
LinearSolver::Summary
SparseSchurComplementSolver::SolveReducedLinearSystemUsingSuiteSparse(
+ const LinearSolver::PerSolveOptions& per_solve_options,
double* solution) {
+#ifdef CERES_NO_SUITESPARSE
+
+ LinearSolver::Summary summary;
+ summary.num_iterations = 0;
+ summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
+ summary.message = "Ceres was not built with SuiteSparse support. "
+ "Therefore, SPARSE_SCHUR cannot be used with SUITE_SPARSE";
+ return summary;
+
+#else
+
LinearSolver::Summary summary;
summary.num_iterations = 0;
summary.termination_type = LINEAR_SOLVER_SUCCESS;
@@ -326,6 +405,8 @@ SparseSchurComplementSolver::SolveReducedLinearSystemUsingSuiteSparse(
if (factor_ == NULL) {
ss_.Free(cholmod_lhs);
summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
+ // No need to set message as it has already been set by the
+ // symbolic analysis routines above.
return summary;
}
@@ -335,6 +416,8 @@ SparseSchurComplementSolver::SolveReducedLinearSystemUsingSuiteSparse(
ss_.Free(cholmod_lhs);
if (summary.termination_type != LINEAR_SOLVER_SUCCESS) {
+ // No need to set message as it has already been set by the
+ // numeric factorization routine above.
return summary;
}
@@ -346,6 +429,8 @@ SparseSchurComplementSolver::SolveReducedLinearSystemUsingSuiteSparse(
ss_.Free(cholmod_rhs);
if (cholmod_solution == NULL) {
+ summary.message =
+ "SuiteSparse failure. Unable to perform triangular solve.";
summary.termination_type = LINEAR_SOLVER_FAILURE;
return summary;
}
@@ -354,23 +439,27 @@ SparseSchurComplementSolver::SolveReducedLinearSystemUsingSuiteSparse(
= VectorRef(static_cast<double*>(cholmod_solution->x), num_rows);
ss_.Free(cholmod_solution);
return summary;
-}
-#else
-LinearSolver::Summary
-SparseSchurComplementSolver::SolveReducedLinearSystemUsingSuiteSparse(
- double* solution) {
- LOG(FATAL) << "No SuiteSparse support in Ceres.";
- return LinearSolver::Summary();
-}
#endif // CERES_NO_SUITESPARSE
+}
-#ifndef CERES_NO_CXSPARSE
// Solve the system Sx = r, assuming that the matrix S is stored in a
// BlockRandomAccessSparseMatrix. The linear system is solved using
// CXSparse's sparse cholesky factorization routines.
LinearSolver::Summary
SparseSchurComplementSolver::SolveReducedLinearSystemUsingCXSparse(
+ const LinearSolver::PerSolveOptions& per_solve_options,
double* solution) {
+#ifdef CERES_NO_CXSPARSE
+
+ LinearSolver::Summary summary;
+ summary.num_iterations = 0;
+ summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
+ summary.message = "Ceres was not built with CXSparse support. "
+ "Therefore, SPARSE_SCHUR cannot be used with CX_SPARSE";
+ return summary;
+
+#else
+
LinearSolver::Summary summary;
summary.num_iterations = 0;
summary.termination_type = LINEAR_SOLVER_SUCCESS;
@@ -407,16 +496,169 @@ SparseSchurComplementSolver::SolveReducedLinearSystemUsingCXSparse(
cxsparse_.Free(lhs);
return summary;
+#endif // CERES_NO_CXPARSE
}
+
+// Solve the system Sx = r, assuming that the matrix S is stored in a
+// BlockRandomAccessSparseMatrix. The linear system is solved using
+// Eigen's sparse cholesky factorization routines.
+LinearSolver::Summary
+SparseSchurComplementSolver::SolveReducedLinearSystemUsingEigen(
+ const LinearSolver::PerSolveOptions& per_solve_options,
+ double* solution) {
+#ifndef CERES_USE_EIGEN_SPARSE
+
+ LinearSolver::Summary summary;
+ summary.num_iterations = 0;
+ summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
+ summary.message =
+ "SPARSE_SCHUR cannot be used with EIGEN_SPARSE. "
+ "Ceres was not built with support for "
+ "Eigen's SimplicialLDLT decomposition. "
+ "This requires enabling building with -DEIGENSPARSE=ON.";
+ return summary;
+
#else
+ EventLogger event_logger("SchurComplementSolver::EigenSolve");
+ LinearSolver::Summary summary;
+ summary.num_iterations = 0;
+ summary.termination_type = LINEAR_SOLVER_SUCCESS;
+ summary.message = "Success.";
+
+ // Extract the TripletSparseMatrix that is used for actually storing S.
+ TripletSparseMatrix* tsm =
+ const_cast<TripletSparseMatrix*>(
+ down_cast<const BlockRandomAccessSparseMatrix*>(lhs())->matrix());
+ const int num_rows = tsm->num_rows();
+
+ // The case where there are no f blocks, and the system is block
+ // diagonal.
+ if (num_rows == 0) {
+ return summary;
+ }
+
+ // This is an upper triangular matrix.
+ CompressedRowSparseMatrix crsm(*tsm);
+ // Map this to a column major, lower triangular matrix.
+ Eigen::MappedSparseMatrix<double, Eigen::ColMajor> eigen_lhs(
+ crsm.num_rows(),
+ crsm.num_rows(),
+ crsm.num_nonzeros(),
+ crsm.mutable_rows(),
+ crsm.mutable_cols(),
+ crsm.mutable_values());
+ event_logger.AddEvent("ToCompressedRowSparseMatrix");
+
+ // Compute symbolic factorization if one does not exist.
+ if (simplicial_ldlt_.get() == NULL) {
+ simplicial_ldlt_.reset(new SimplicialLDLT);
+ // This ordering is quite bad. The scalar ordering produced by the
+ // AMD algorithm is quite bad and can be an order of magnitude
+ // worse than the one computed using the block version of the
+ // algorithm.
+ simplicial_ldlt_->analyzePattern(eigen_lhs);
+ event_logger.AddEvent("Analysis");
+ if (simplicial_ldlt_->info() != Eigen::Success) {
+ summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
+ summary.message =
+ "Eigen failure. Unable to find symbolic factorization.";
+ return summary;
+ }
+ }
+
+ simplicial_ldlt_->factorize(eigen_lhs);
+ event_logger.AddEvent("Factorize");
+ if (simplicial_ldlt_->info() != Eigen::Success) {
+ summary.termination_type = LINEAR_SOLVER_FAILURE;
+ summary.message = "Eigen failure. Unable to find numeric factoriztion.";
+ return summary;
+ }
+
+ VectorRef(solution, num_rows) =
+ simplicial_ldlt_->solve(ConstVectorRef(rhs(), num_rows));
+ event_logger.AddEvent("Solve");
+ if (simplicial_ldlt_->info() != Eigen::Success) {
+ summary.termination_type = LINEAR_SOLVER_FAILURE;
+ summary.message = "Eigen failure. Unable to do triangular solve.";
+ }
+
+ return summary;
+#endif // CERES_USE_EIGEN_SPARSE
+}
+
LinearSolver::Summary
-SparseSchurComplementSolver::SolveReducedLinearSystemUsingCXSparse(
+SparseSchurComplementSolver::SolveReducedLinearSystemUsingConjugateGradients(
+ const LinearSolver::PerSolveOptions& per_solve_options,
double* solution) {
- LOG(FATAL) << "No CXSparse support in Ceres.";
- return LinearSolver::Summary();
+ const int num_rows = lhs()->num_rows();
+ // The case where there are no f blocks, and the system is block
+ // diagonal.
+ if (num_rows == 0) {
+ LinearSolver::Summary summary;
+ summary.num_iterations = 0;
+ summary.termination_type = LINEAR_SOLVER_SUCCESS;
+ summary.message = "Success.";
+ return summary;
+ }
+
+ // Only SCHUR_JACOBI is supported over here right now.
+ CHECK_EQ(options().preconditioner_type, SCHUR_JACOBI);
+
+ if (preconditioner_.get() == NULL) {
+ preconditioner_.reset(new BlockRandomAccessDiagonalMatrix(blocks_));
+ }
+
+ BlockRandomAccessSparseMatrix* sc =
+ down_cast<BlockRandomAccessSparseMatrix*>(
+ const_cast<BlockRandomAccessMatrix*>(lhs()));
+
+ // Extract block diagonal from the Schur complement to construct the
+ // schur_jacobi preconditioner.
+ for (int i = 0; i < blocks_.size(); ++i) {
+ const int block_size = blocks_[i];
+
+ int sc_r, sc_c, sc_row_stride, sc_col_stride;
+ CellInfo* sc_cell_info =
+ CHECK_NOTNULL(sc->GetCell(i, i,
+ &sc_r, &sc_c,
+ &sc_row_stride, &sc_col_stride));
+ MatrixRef sc_m(sc_cell_info->values, sc_row_stride, sc_col_stride);
+
+ int pre_r, pre_c, pre_row_stride, pre_col_stride;
+ CellInfo* pre_cell_info = CHECK_NOTNULL(
+ preconditioner_->GetCell(i, i,
+ &pre_r, &pre_c,
+ &pre_row_stride, &pre_col_stride));
+ MatrixRef pre_m(pre_cell_info->values, pre_row_stride, pre_col_stride);
+
+ pre_m.block(pre_r, pre_c, block_size, block_size) =
+ sc_m.block(sc_r, sc_c, block_size, block_size);
+ }
+ preconditioner_->Invert();
+
+ VectorRef(solution, num_rows).setZero();
+
+ scoped_ptr<LinearOperator> lhs_adapter(
+ new BlockRandomAccessSparseMatrixAdapter(*sc));
+ scoped_ptr<LinearOperator> preconditioner_adapter(
+ new BlockRandomAccessDiagonalMatrixAdapter(*preconditioner_));
+
+
+ LinearSolver::Options cg_options;
+ cg_options.min_num_iterations = options().min_num_iterations;
+ cg_options.max_num_iterations = options().max_num_iterations;
+ ConjugateGradientsSolver cg_solver(cg_options);
+
+ LinearSolver::PerSolveOptions cg_per_solve_options;
+ cg_per_solve_options.r_tolerance = per_solve_options.r_tolerance;
+ cg_per_solve_options.q_tolerance = per_solve_options.q_tolerance;
+ cg_per_solve_options.preconditioner = preconditioner_adapter.get();
+
+ return cg_solver.Solve(lhs_adapter.get(),
+ rhs(),
+ cg_per_solve_options,
+ solution);
}
-#endif // CERES_NO_CXPARSE
-#endif // !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARE)
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h
index a9978518b17..93d23e3d012 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/schur_complement_solver.h
@@ -35,6 +35,8 @@
#include <utility>
#include <vector>
+#include "ceres/internal/port.h"
+
#include "ceres/block_random_access_matrix.h"
#include "ceres/block_sparse_matrix.h"
#include "ceres/block_structure.h"
@@ -44,6 +46,12 @@
#include "ceres/suitesparse.h"
#include "ceres/internal/scoped_ptr.h"
#include "ceres/types.h"
+#include "ceres/block_random_access_diagonal_matrix.h"
+
+#ifdef CERES_USE_EIGEN_SPARSE
+#include "Eigen/SparseCholesky"
+#include "Eigen/OrderingMethods"
+#endif
namespace ceres {
namespace internal {
@@ -127,6 +135,7 @@ class SchurComplementSolver : public BlockSparseMatrixSolver {
private:
virtual void InitStorage(const CompressedRowBlockStructure* bs) = 0;
virtual LinearSolver::Summary SolveReducedLinearSystem(
+ const LinearSolver::PerSolveOptions& per_solve_options,
double* solution) = 0;
LinearSolver::Options options_;
@@ -148,12 +157,12 @@ class DenseSchurComplementSolver : public SchurComplementSolver {
private:
virtual void InitStorage(const CompressedRowBlockStructure* bs);
virtual LinearSolver::Summary SolveReducedLinearSystem(
+ const LinearSolver::PerSolveOptions& per_solve_options,
double* solution);
CERES_DISALLOW_COPY_AND_ASSIGN(DenseSchurComplementSolver);
};
-#if !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARE)
// Sparse Cholesky factorization based solver.
class SparseSchurComplementSolver : public SchurComplementSolver {
public:
@@ -163,10 +172,19 @@ class SparseSchurComplementSolver : public SchurComplementSolver {
private:
virtual void InitStorage(const CompressedRowBlockStructure* bs);
virtual LinearSolver::Summary SolveReducedLinearSystem(
+ const LinearSolver::PerSolveOptions& per_solve_options,
double* solution);
LinearSolver::Summary SolveReducedLinearSystemUsingSuiteSparse(
+ const LinearSolver::PerSolveOptions& per_solve_options,
double* solution);
LinearSolver::Summary SolveReducedLinearSystemUsingCXSparse(
+ const LinearSolver::PerSolveOptions& per_solve_options,
+ double* solution);
+ LinearSolver::Summary SolveReducedLinearSystemUsingEigen(
+ const LinearSolver::PerSolveOptions& per_solve_options,
+ double* solution);
+ LinearSolver::Summary SolveReducedLinearSystemUsingConjugateGradients(
+ const LinearSolver::PerSolveOptions& per_solve_options,
double* solution);
// Size of the blocks in the Schur complement.
@@ -180,10 +198,28 @@ class SparseSchurComplementSolver : public SchurComplementSolver {
CXSparse cxsparse_;
// Cached factorization
cs_dis* cxsparse_factor_;
+
+#ifdef CERES_USE_EIGEN_SPARSE
+
+ // The preprocessor gymnastics here are dealing with the fact that
+ // before version 3.2.2, Eigen did not support a third template
+ // parameter to specify the ordering.
+#if EIGEN_VERSION_AT_LEAST(3,2,2)
+ typedef Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>, Eigen::Lower,
+ Eigen::NaturalOrdering<int> >
+ SimplicialLDLT;
+#else
+ typedef Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>, Eigen::Lower>
+ SimplicialLDLT;
+#endif
+
+ scoped_ptr<SimplicialLDLT> simplicial_ldlt_;
+#endif
+
+ scoped_ptr<BlockRandomAccessDiagonalMatrix> preconditioner_;
CERES_DISALLOW_COPY_AND_ASSIGN(SparseSchurComplementSolver);
};
-#endif // !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARE)
} // namespace internal
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.cc b/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.cc
index 6dc9e89d3cc..cbdb7086102 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.cc
@@ -32,7 +32,6 @@
#include <utility>
#include <vector>
-#include "Eigen/Dense"
#include "ceres/block_random_access_diagonal_matrix.h"
#include "ceres/block_sparse_matrix.h"
#include "ceres/collections_port.h"
@@ -55,12 +54,12 @@ SchurJacobiPreconditioner::SchurJacobiPreconditioner(
<< "Jacobian should have atleast 1 f_block for "
<< "SCHUR_JACOBI preconditioner.";
- block_size_.resize(num_blocks);
+ vector<int> blocks(num_blocks);
for (int i = 0; i < num_blocks; ++i) {
- block_size_[i] = bs.cols[i + options_.elimination_groups[0]].size;
+ blocks[i] = bs.cols[i + options_.elimination_groups[0]].size;
}
- m_.reset(new BlockRandomAccessDiagonalMatrix(block_size_));
+ m_.reset(new BlockRandomAccessDiagonalMatrix(blocks));
InitEliminator(bs);
}
@@ -99,32 +98,13 @@ bool SchurJacobiPreconditioner::UpdateImpl(const BlockSparseMatrix& A,
// Compute a subset of the entries of the Schur complement.
eliminator_->Eliminate(&A, b.data(), D, m_.get(), rhs.data());
+ m_->Invert();
return true;
}
void SchurJacobiPreconditioner::RightMultiply(const double* x,
double* y) const {
- CHECK_NOTNULL(x);
- CHECK_NOTNULL(y);
-
- const double* lhs_values =
- down_cast<BlockRandomAccessDiagonalMatrix*>(m_.get())->matrix()->values();
-
- // This loop can be easily multi-threaded with OpenMP if need be.
- for (int i = 0; i < block_size_.size(); ++i) {
- const int block_size = block_size_[i];
- ConstMatrixRef block(lhs_values, block_size, block_size);
-
- VectorRef(y, block_size) =
- block
- .selfadjointView<Eigen::Upper>()
- .llt()
- .solve(ConstVectorRef(x, block_size));
-
- x += block_size;
- y += block_size;
- lhs_values += block_size * block_size;
- }
+ m_->RightMultiply(x, y);
}
int SchurJacobiPreconditioner::num_rows() const {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.h
index aecb0151083..8b528e25075 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/schur_jacobi_preconditioner.h
@@ -94,11 +94,7 @@ class SchurJacobiPreconditioner : public BlockSparseMatrixPreconditioner {
virtual bool UpdateImpl(const BlockSparseMatrix& A, const double* D);
Preconditioner::Options options_;
-
- // Sizes of the blocks in the schur complement.
- vector<int> block_size_;
scoped_ptr<SchurEliminatorBase> eliminator_;
-
// Preconditioner matrix.
scoped_ptr<BlockRandomAccessDiagonalMatrix> m_;
CERES_DISALLOW_COPY_AND_ASSIGN(SchurJacobiPreconditioner);
diff --git a/extern/libmv/third_party/ceres/internal/ceres/single_linkage_clustering.cc b/extern/libmv/third_party/ceres/internal/ceres/single_linkage_clustering.cc
index 0a8b20cfe29..f0f7e0e1e06 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/single_linkage_clustering.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/single_linkage_clustering.cc
@@ -44,7 +44,7 @@ namespace internal {
int ComputeSingleLinkageClustering(
const SingleLinkageClusteringOptions& options,
- const Graph<int>& graph,
+ const WeightedGraph<int>& graph,
HashMap<int, int>* membership) {
CHECK_NOTNULL(membership)->clear();
diff --git a/extern/libmv/third_party/ceres/internal/ceres/single_linkage_clustering.h b/extern/libmv/third_party/ceres/internal/ceres/single_linkage_clustering.h
index e6fdeabea61..79c4da114c2 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/single_linkage_clustering.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/single_linkage_clustering.h
@@ -64,7 +64,7 @@ struct SingleLinkageClusteringOptions {
// identified by the algorithm.
int ComputeSingleLinkageClustering(
const SingleLinkageClusteringOptions& options,
- const Graph<int>& graph,
+ const WeightedGraph<int>& graph,
HashMap<int, int>* membership);
} // namespace internal
diff --git a/extern/libmv/third_party/ceres/internal/ceres/small_blas.h b/extern/libmv/third_party/ceres/internal/ceres/small_blas.h
index 26228e49306..5639664b925 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/small_blas.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/small_blas.h
@@ -42,30 +42,6 @@
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
-
// The following three macros are used to share code and reduce
// template junk across the various GEMM variants.
#define CERES_GEMM_BEGIN(name) \
@@ -168,11 +144,11 @@ CERES_GEMM_BEGIN(MatrixMatrixMultiplyEigen) {
block(Cref, start_row_c, start_col_c, num_row_a, num_col_b);
if (kOperation > 0) {
- block CERES_MAYBE_NOALIAS += Aref * Bref;
+ block.noalias() += Aref * Bref;
} else if (kOperation < 0) {
- block CERES_MAYBE_NOALIAS -= Aref * Bref;
+ block.noalias() -= Aref * Bref;
} else {
- block CERES_MAYBE_NOALIAS = Aref * Bref;
+ block.noalias() = Aref * Bref;
}
}
@@ -228,11 +204,11 @@ CERES_GEMM_BEGIN(MatrixTransposeMatrixMultiplyEigen) {
start_row_c, start_col_c,
num_col_a, num_col_b);
if (kOperation > 0) {
- block CERES_MAYBE_NOALIAS += Aref.transpose() * Bref;
+ block.noalias() += Aref.transpose() * Bref;
} else if (kOperation < 0) {
- block CERES_MAYBE_NOALIAS -= Aref.transpose() * Bref;
+ block.noalias() -= Aref.transpose() * Bref;
} else {
- block CERES_MAYBE_NOALIAS = Aref.transpose() * Bref;
+ block.noalias() = Aref.transpose() * Bref;
}
}
@@ -394,8 +370,6 @@ inline void MatrixTransposeVectorMultiply(const double* A,
#endif // CERES_NO_CUSTOM_BLAS
}
-
-#undef CERES_MAYBE_NOALIAS
#undef CERES_GEMM_BEGIN
#undef CERES_GEMM_EIGEN_HEADER
#undef CERES_GEMM_NAIVE_HEADER
diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver.cc b/extern/libmv/third_party/ceres/internal/ceres/solver.cc
index 53a9b4b7220..3512e156f9e 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/solver.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/solver.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
+// Copyright 2014 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -31,17 +31,282 @@
#include "ceres/solver.h"
+#include <algorithm>
+#include <sstream> // NOLINT
#include <vector>
+#include "ceres/gradient_checking_cost_function.h"
+#include "ceres/internal/port.h"
+#include "ceres/parameter_block_ordering.h"
+#include "ceres/preprocessor.h"
#include "ceres/problem.h"
#include "ceres/problem_impl.h"
#include "ceres/program.h"
-#include "ceres/solver_impl.h"
+#include "ceres/solver_utils.h"
#include "ceres/stringprintf.h"
+#include "ceres/types.h"
#include "ceres/wall_time.h"
namespace ceres {
namespace {
+#define OPTION_OP(x, y, OP) \
+ if (!(options.x OP y)) { \
+ std::stringstream ss; \
+ ss << "Invalid configuration. "; \
+ ss << string("Solver::Options::" #x " = ") << options.x << ". "; \
+ ss << "Violated constraint: "; \
+ ss << string("Solver::Options::" #x " " #OP " "#y); \
+ *error = ss.str(); \
+ return false; \
+ }
+
+#define OPTION_OP_OPTION(x, y, OP) \
+ if (!(options.x OP options.y)) { \
+ std::stringstream ss; \
+ ss << "Invalid configuration. "; \
+ ss << string("Solver::Options::" #x " = ") << options.x << ". "; \
+ ss << string("Solver::Options::" #y " = ") << options.y << ". "; \
+ ss << "Violated constraint: "; \
+ ss << string("Solver::Options::" #x); \
+ ss << string(#OP " Solver::Options::" #y "."); \
+ *error = ss.str(); \
+ return false; \
+ }
+
+#define OPTION_GE(x, y) OPTION_OP(x, y, >=);
+#define OPTION_GT(x, y) OPTION_OP(x, y, >);
+#define OPTION_LE(x, y) OPTION_OP(x, y, <=);
+#define OPTION_LT(x, y) OPTION_OP(x, y, <);
+#define OPTION_LE_OPTION(x, y) OPTION_OP_OPTION(x, y, <=)
+#define OPTION_LT_OPTION(x, y) OPTION_OP_OPTION(x, y, <)
+
+bool CommonOptionsAreValid(const Solver::Options& options, string* error) {
+ OPTION_GE(max_num_iterations, 0);
+ OPTION_GE(max_solver_time_in_seconds, 0.0);
+ OPTION_GE(function_tolerance, 0.0);
+ OPTION_GE(gradient_tolerance, 0.0);
+ OPTION_GE(parameter_tolerance, 0.0);
+ OPTION_GT(num_threads, 0);
+ OPTION_GT(num_linear_solver_threads, 0);
+ if (options.check_gradients) {
+ OPTION_GT(gradient_check_relative_precision, 0.0);
+ OPTION_GT(numeric_derivative_relative_step_size, 0.0);
+ }
+ return true;
+}
+
+bool TrustRegionOptionsAreValid(const Solver::Options& options, string* error) {
+ OPTION_GT(initial_trust_region_radius, 0.0);
+ OPTION_GT(min_trust_region_radius, 0.0);
+ OPTION_GT(max_trust_region_radius, 0.0);
+ OPTION_LE_OPTION(min_trust_region_radius, max_trust_region_radius);
+ OPTION_LE_OPTION(min_trust_region_radius, initial_trust_region_radius);
+ OPTION_LE_OPTION(initial_trust_region_radius, max_trust_region_radius);
+ OPTION_GE(min_relative_decrease, 0.0);
+ OPTION_GE(min_lm_diagonal, 0.0);
+ OPTION_GE(max_lm_diagonal, 0.0);
+ OPTION_LE_OPTION(min_lm_diagonal, max_lm_diagonal);
+ OPTION_GE(max_num_consecutive_invalid_steps, 0);
+ OPTION_GT(eta, 0.0);
+ OPTION_GE(min_linear_solver_iterations, 0);
+ OPTION_GE(max_linear_solver_iterations, 1);
+ OPTION_LE_OPTION(min_linear_solver_iterations, max_linear_solver_iterations);
+
+ if (options.use_inner_iterations) {
+ OPTION_GE(inner_iteration_tolerance, 0.0);
+ }
+
+ if (options.use_nonmonotonic_steps) {
+ OPTION_GT(max_consecutive_nonmonotonic_steps, 0);
+ }
+
+ if (options.linear_solver_type == ITERATIVE_SCHUR &&
+ options.use_explicit_schur_complement &&
+ options.preconditioner_type != SCHUR_JACOBI) {
+ *error = "use_explicit_schur_complement only supports "
+ "SCHUR_JACOBI as the preconditioner.";
+ return false;
+ }
+
+ if (options.preconditioner_type == CLUSTER_JACOBI &&
+ options.sparse_linear_algebra_library_type != SUITE_SPARSE) {
+ *error = "CLUSTER_JACOBI requires "
+ "Solver::Options::sparse_linear_algebra_library_type to be "
+ "SUITE_SPARSE";
+ return false;
+ }
+
+ if (options.preconditioner_type == CLUSTER_TRIDIAGONAL &&
+ options.sparse_linear_algebra_library_type != SUITE_SPARSE) {
+ *error = "CLUSTER_TRIDIAGONAL requires "
+ "Solver::Options::sparse_linear_algebra_library_type to be "
+ "SUITE_SPARSE";
+ return false;
+ }
+
+#ifdef CERES_NO_LAPACK
+ if (options.dense_linear_algebra_library_type == LAPACK) {
+ if (options.linear_solver_type == DENSE_NORMAL_CHOLESKY) {
+ *error = "Can't use DENSE_NORMAL_CHOLESKY with LAPACK because "
+ "LAPACK was not enabled when Ceres was built.";
+ return false;
+ }
+
+ if (options.linear_solver_type == DENSE_QR) {
+ *error = "Can't use DENSE_QR with LAPACK because "
+ "LAPACK was not enabled when Ceres was built.";
+ return false;
+ }
+
+ if (options.linear_solver_type == DENSE_SCHUR) {
+ *error = "Can't use DENSE_SCHUR with LAPACK because "
+ "LAPACK was not enabled when Ceres was built.";
+ return false;
+ }
+ }
+#endif
+
+#ifdef CERES_NO_SUITESPARSE
+ if (options.sparse_linear_algebra_library_type == SUITE_SPARSE) {
+ if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY) {
+ *error = "Can't use SPARSE_NORMAL_CHOLESKY with SUITESPARSE because "
+ "SuiteSparse was not enabled when Ceres was built.";
+ return false;
+ }
+
+ if (options.linear_solver_type == SPARSE_SCHUR) {
+ *error = "Can't use SPARSE_SCHUR with SUITESPARSE because "
+ "SuiteSparse was not enabled when Ceres was built.";
+ return false;
+ }
+
+ if (options.preconditioner_type == CLUSTER_JACOBI) {
+ *error = "CLUSTER_JACOBI preconditioner not supported. "
+ "SuiteSparse was not enabled when Ceres was built.";
+ return false;
+ }
+
+ if (options.preconditioner_type == CLUSTER_TRIDIAGONAL) {
+ *error = "CLUSTER_TRIDIAGONAL preconditioner not supported. "
+ "SuiteSparse was not enabled when Ceres was built.";
+ return false;
+ }
+ }
+#endif
+
+#ifdef CERES_NO_CXSPARSE
+ if (options.sparse_linear_algebra_library_type == CX_SPARSE) {
+ if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY) {
+ *error = "Can't use SPARSE_NORMAL_CHOLESKY with CX_SPARSE because "
+ "CXSparse was not enabled when Ceres was built.";
+ return false;
+ }
+
+ if (options.linear_solver_type == SPARSE_SCHUR) {
+ *error = "Can't use SPARSE_SCHUR with CX_SPARSE because "
+ "CXSparse was not enabled when Ceres was built.";
+ return false;
+ }
+ }
+#endif
+
+#ifndef CERES_USE_EIGEN_SPARSE
+ if (options.sparse_linear_algebra_library_type == EIGEN_SPARSE) {
+ if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY) {
+ *error = "Can't use SPARSE_NORMAL_CHOLESKY with EIGEN_SPARSE because "
+ "Eigen's sparse linear algebra was not enabled when Ceres was "
+ "built.";
+ return false;
+ }
+
+ if (options.linear_solver_type == SPARSE_SCHUR) {
+ *error = "Can't use SPARSE_SCHUR with EIGEN_SPARSE because "
+ "Eigen's sparse linear algebra was not enabled when Ceres was "
+ "built.";
+ return false;
+ }
+ }
+#endif
+
+ if (options.trust_region_strategy_type == DOGLEG) {
+ if (options.linear_solver_type == ITERATIVE_SCHUR ||
+ options.linear_solver_type == CGNR) {
+ *error = "DOGLEG only supports exact factorization based linear "
+ "solvers. If you want to use an iterative solver please "
+ "use LEVENBERG_MARQUARDT as the trust_region_strategy_type";
+ return false;
+ }
+ }
+
+ if (options.trust_region_minimizer_iterations_to_dump.size() > 0 &&
+ options.trust_region_problem_dump_format_type != CONSOLE &&
+ options.trust_region_problem_dump_directory.empty()) {
+ *error = "Solver::Options::trust_region_problem_dump_directory is empty.";
+ return false;
+ }
+
+ if (options.dynamic_sparsity &&
+ options.linear_solver_type != SPARSE_NORMAL_CHOLESKY) {
+ *error = "Dynamic sparsity is only supported with SPARSE_NORMAL_CHOLESKY.";
+ return false;
+ }
+
+ return true;
+}
+
+bool LineSearchOptionsAreValid(const Solver::Options& options, string* error) {
+ OPTION_GT(max_lbfgs_rank, 0);
+ OPTION_GT(min_line_search_step_size, 0.0);
+ OPTION_GT(max_line_search_step_contraction, 0.0);
+ OPTION_LT(max_line_search_step_contraction, 1.0);
+ OPTION_LT_OPTION(max_line_search_step_contraction,
+ min_line_search_step_contraction);
+ OPTION_LE(min_line_search_step_contraction, 1.0);
+ OPTION_GT(max_num_line_search_step_size_iterations, 0);
+ OPTION_GT(line_search_sufficient_function_decrease, 0.0);
+ OPTION_LT_OPTION(line_search_sufficient_function_decrease,
+ line_search_sufficient_curvature_decrease);
+ OPTION_LT(line_search_sufficient_curvature_decrease, 1.0);
+ OPTION_GT(max_line_search_step_expansion, 1.0);
+
+ if ((options.line_search_direction_type == ceres::BFGS ||
+ options.line_search_direction_type == ceres::LBFGS) &&
+ options.line_search_type != ceres::WOLFE) {
+ *error =
+ string("Invalid configuration: Solver::Options::line_search_type = ")
+ + string(LineSearchTypeToString(options.line_search_type))
+ + string(". When using (L)BFGS, "
+ "Solver::Options::line_search_type must be set to WOLFE.");
+ return false;
+ }
+
+ // Warn user if they have requested BISECTION interpolation, but constraints
+ // on max/min step size change during line search prevent bisection scaling
+ // from occurring. Warn only, as this is likely a user mistake, but one which
+ // does not prevent us from continuing.
+ LOG_IF(WARNING,
+ (options.line_search_interpolation_type == ceres::BISECTION &&
+ (options.max_line_search_step_contraction > 0.5 ||
+ options.min_line_search_step_contraction < 0.5)))
+ << "Line search interpolation type is BISECTION, but specified "
+ << "max_line_search_step_contraction: "
+ << options.max_line_search_step_contraction << ", and "
+ << "min_line_search_step_contraction: "
+ << options.min_line_search_step_contraction
+ << ", prevent bisection (0.5) scaling, continuing with solve regardless.";
+
+ return true;
+}
+
+#undef OPTION_OP
+#undef OPTION_OP_OPTION
+#undef OPTION_GT
+#undef OPTION_GE
+#undef OPTION_LE
+#undef OPTION_LT
+#undef OPTION_LE_OPTION
+#undef OPTION_LT_OPTION
+
void StringifyOrdering(const vector<int>& ordering, string* report) {
if (ordering.size() == 0) {
internal::StringAppendF(report, "AUTOMATIC");
@@ -54,19 +319,211 @@ void StringifyOrdering(const vector<int>& ordering, string* report) {
internal::StringAppendF(report, "%d", ordering.back());
}
+void SummarizeGivenProgram(const internal::Program& program,
+ Solver::Summary* summary) {
+ summary->num_parameter_blocks = program.NumParameterBlocks();
+ summary->num_parameters = program.NumParameters();
+ summary->num_effective_parameters = program.NumEffectiveParameters();
+ summary->num_residual_blocks = program.NumResidualBlocks();
+ summary->num_residuals = program.NumResiduals();
+}
+
+void SummarizeReducedProgram(const internal::Program& program,
+ Solver::Summary* summary) {
+ summary->num_parameter_blocks_reduced = program.NumParameterBlocks();
+ summary->num_parameters_reduced = program.NumParameters();
+ summary->num_effective_parameters_reduced = program.NumEffectiveParameters();
+ summary->num_residual_blocks_reduced = program.NumResidualBlocks();
+ summary->num_residuals_reduced = program.NumResiduals();
+}
+
+void PreSolveSummarize(const Solver::Options& options,
+ const internal::ProblemImpl* problem,
+ Solver::Summary* summary) {
+ SummarizeGivenProgram(problem->program(), summary);
+ internal::OrderingToGroupSizes(options.linear_solver_ordering.get(),
+ &(summary->linear_solver_ordering_given));
+ internal::OrderingToGroupSizes(options.inner_iteration_ordering.get(),
+ &(summary->inner_iteration_ordering_given));
+
+ summary->dense_linear_algebra_library_type = options.dense_linear_algebra_library_type; // NOLINT
+ summary->dogleg_type = options.dogleg_type;
+ summary->inner_iteration_time_in_seconds = 0.0;
+ summary->inner_iterations_given = options.use_inner_iterations;
+ summary->line_search_direction_type = options.line_search_direction_type; // NOLINT
+ summary->line_search_interpolation_type = options.line_search_interpolation_type; // NOLINT
+ summary->line_search_type = options.line_search_type;
+ summary->linear_solver_type_given = options.linear_solver_type;
+ summary->max_lbfgs_rank = options.max_lbfgs_rank;
+ summary->minimizer_type = options.minimizer_type;
+ summary->nonlinear_conjugate_gradient_type = options.nonlinear_conjugate_gradient_type; // NOLINT
+ summary->num_linear_solver_threads_given = options.num_linear_solver_threads; // NOLINT
+ summary->num_threads_given = options.num_threads;
+ summary->preconditioner_type_given = options.preconditioner_type;
+ summary->sparse_linear_algebra_library_type = options.sparse_linear_algebra_library_type; // NOLINT
+ summary->trust_region_strategy_type = options.trust_region_strategy_type; // NOLINT
+ summary->visibility_clustering_type = options.visibility_clustering_type; // NOLINT
+}
+
+void PostSolveSummarize(const internal::PreprocessedProblem& pp,
+ Solver::Summary* summary) {
+ internal::OrderingToGroupSizes(pp.options.linear_solver_ordering.get(),
+ &(summary->linear_solver_ordering_used));
+ internal::OrderingToGroupSizes(pp.options.inner_iteration_ordering.get(),
+ &(summary->inner_iteration_ordering_used));
+
+ summary->inner_iterations_used = pp.inner_iteration_minimizer.get() != NULL; // NOLINT
+ summary->linear_solver_type_used = pp.options.linear_solver_type;
+ summary->num_linear_solver_threads_used = pp.options.num_linear_solver_threads; // NOLINT
+ summary->num_threads_used = pp.options.num_threads;
+ summary->preconditioner_type_used = pp.options.preconditioner_type; // NOLINT
+
+ internal::SetSummaryFinalCost(summary);
+
+ if (pp.reduced_program.get() != NULL) {
+ SummarizeReducedProgram(*pp.reduced_program, summary);
+ }
+
+ // It is possible that no evaluator was created. This would be the
+ // case if the preprocessor failed, or if the reduced problem did
+ // not contain any parameter blocks. Thus, only extract the
+ // evaluator statistics if one exists.
+ if (pp.evaluator.get() != NULL) {
+ const map<string, double>& evaluator_time_statistics =
+ pp.evaluator->TimeStatistics();
+ summary->residual_evaluation_time_in_seconds =
+ FindWithDefault(evaluator_time_statistics, "Evaluator::Residual", 0.0);
+ summary->jacobian_evaluation_time_in_seconds =
+ FindWithDefault(evaluator_time_statistics, "Evaluator::Jacobian", 0.0);
+ }
+
+ // Again, like the evaluator, there may or may not be a linear
+ // solver from which we can extract run time statistics. In
+ // particular the line search solver does not use a linear solver.
+ if (pp.linear_solver.get() != NULL) {
+ const map<string, double>& linear_solver_time_statistics =
+ pp.linear_solver->TimeStatistics();
+ summary->linear_solver_time_in_seconds =
+ FindWithDefault(linear_solver_time_statistics,
+ "LinearSolver::Solve",
+ 0.0);
+ }
+}
+
+void Minimize(internal::PreprocessedProblem* pp,
+ Solver::Summary* summary) {
+ using internal::Program;
+ using internal::scoped_ptr;
+ using internal::Minimizer;
+
+ Program* program = pp->reduced_program.get();
+ if (pp->reduced_program->NumParameterBlocks() == 0) {
+ summary->message = "Function tolerance reached. "
+ "No non-constant parameter blocks found.";
+ summary->termination_type = CONVERGENCE;
+ VLOG_IF(1, pp->options.logging_type != SILENT) << summary->message;
+ summary->initial_cost = summary->fixed_cost;
+ summary->final_cost = summary->fixed_cost;
+ return;
+ }
+
+ scoped_ptr<Minimizer> minimizer(
+ Minimizer::Create(pp->options.minimizer_type));
+ minimizer->Minimize(pp->minimizer_options,
+ pp->reduced_parameters.data(),
+ summary);
+
+ if (summary->IsSolutionUsable()) {
+ program->StateVectorToParameterBlocks(pp->reduced_parameters.data());
+ program->CopyParameterBlockStateToUserState();
+ }
+}
+
} // namespace
+bool Solver::Options::IsValid(string* error) const {
+ if (!CommonOptionsAreValid(*this, error)) {
+ return false;
+ }
+
+ if (minimizer_type == TRUST_REGION) {
+ return TrustRegionOptionsAreValid(*this, error);
+ }
+
+ CHECK_EQ(minimizer_type, LINE_SEARCH);
+ return LineSearchOptionsAreValid(*this, error);
+}
+
Solver::~Solver() {}
void Solver::Solve(const Solver::Options& options,
Problem* problem,
Solver::Summary* summary) {
- double start_time_seconds = internal::WallTimeInSeconds();
- internal::ProblemImpl* problem_impl =
- CHECK_NOTNULL(problem)->problem_impl_.get();
- internal::SolverImpl::Solve(options, problem_impl, summary);
- summary->total_time_in_seconds =
- internal::WallTimeInSeconds() - start_time_seconds;
+ using internal::PreprocessedProblem;
+ using internal::Preprocessor;
+ using internal::ProblemImpl;
+ using internal::Program;
+ using internal::scoped_ptr;
+ using internal::WallTimeInSeconds;
+
+ CHECK_NOTNULL(problem);
+ CHECK_NOTNULL(summary);
+
+ double start_time = WallTimeInSeconds();
+ *summary = Summary();
+ if (!options.IsValid(&summary->message)) {
+ LOG(ERROR) << "Terminating: " << summary->message;
+ return;
+ }
+
+ ProblemImpl* problem_impl = problem->problem_impl_.get();
+ Program* program = problem_impl->mutable_program();
+ PreSolveSummarize(options, problem_impl, summary);
+
+ // Make sure that all the parameter blocks states are set to the
+ // values provided by the user.
+ program->SetParameterBlockStatePtrsToUserStatePtrs();
+
+ scoped_ptr<internal::ProblemImpl> gradient_checking_problem;
+ if (options.check_gradients) {
+ gradient_checking_problem.reset(
+ CreateGradientCheckingProblemImpl(
+ problem_impl,
+ options.numeric_derivative_relative_step_size,
+ options.gradient_check_relative_precision));
+ problem_impl = gradient_checking_problem.get();
+ program = problem_impl->mutable_program();
+ }
+
+ scoped_ptr<Preprocessor> preprocessor(
+ Preprocessor::Create(options.minimizer_type));
+ PreprocessedProblem pp;
+ const bool status = preprocessor->Preprocess(options, problem_impl, &pp);
+ summary->fixed_cost = pp.fixed_cost;
+ summary->preprocessor_time_in_seconds = WallTimeInSeconds() - start_time;
+
+ if (status) {
+ const double minimizer_start_time = WallTimeInSeconds();
+ Minimize(&pp, summary);
+ summary->minimizer_time_in_seconds =
+ WallTimeInSeconds() - minimizer_start_time;
+ } else {
+ summary->message = pp.error;
+ }
+
+ const double postprocessor_start_time = WallTimeInSeconds();
+ problem_impl = problem->problem_impl_.get();
+ program = problem_impl->mutable_program();
+ // On exit, ensure that the parameter blocks again point at the user
+ // provided values and the parameter blocks are numbered according
+ // to their position in the original user provided program.
+ program->SetParameterBlockStatePtrsToUserStatePtrs();
+ program->SetParameterOffsetsAndIndex();
+ PostSolveSummarize(pp, summary);
+ summary->postprocessor_time_in_seconds =
+ WallTimeInSeconds() - postprocessor_start_time;
+
+ summary->total_time_in_seconds = WallTimeInSeconds() - start_time;
}
void Solve(const Solver::Options& options,
@@ -114,7 +571,8 @@ Solver::Summary::Summary()
linear_solver_type_used(SPARSE_NORMAL_CHOLESKY),
inner_iterations_given(false),
inner_iterations_used(false),
- preconditioner_type(IDENTITY),
+ preconditioner_type_given(IDENTITY),
+ preconditioner_type_used(IDENTITY),
visibility_clustering_type(CANONICAL_VIEWS),
trust_region_strategy_type(LEVENBERG_MARQUARDT),
dense_linear_algebra_library_type(EIGEN),
@@ -142,10 +600,9 @@ string Solver::Summary::BriefReport() const {
};
string Solver::Summary::FullReport() const {
- string report =
- "\n"
- "Ceres Solver Report\n"
- "-------------------\n";
+ using internal::VersionString;
+
+ string report = string("\nSolver Summary (v " + VersionString() + ")\n\n");
StringAppendF(&report, "%45s %21s\n", "Original", "Reduced");
StringAppendF(&report, "Parameter blocks % 25d% 25d\n",
@@ -177,8 +634,8 @@ string Solver::Summary::FullReport() const {
if (linear_solver_type_used == SPARSE_NORMAL_CHOLESKY ||
linear_solver_type_used == SPARSE_SCHUR ||
(linear_solver_type_used == ITERATIVE_SCHUR &&
- (preconditioner_type == CLUSTER_JACOBI ||
- preconditioner_type == CLUSTER_TRIDIAGONAL))) {
+ (preconditioner_type_used == CLUSTER_JACOBI ||
+ preconditioner_type_used == CLUSTER_TRIDIAGONAL))) {
StringAppendF(&report, "\nSparse linear algebra library %15s\n",
SparseLinearAlgebraLibraryTypeToString(
sparse_linear_algebra_library_type));
@@ -205,12 +662,12 @@ string Solver::Summary::FullReport() const {
if (linear_solver_type_given == CGNR ||
linear_solver_type_given == ITERATIVE_SCHUR) {
StringAppendF(&report, "Preconditioner %25s%25s\n",
- PreconditionerTypeToString(preconditioner_type),
- PreconditionerTypeToString(preconditioner_type));
+ PreconditionerTypeToString(preconditioner_type_given),
+ PreconditionerTypeToString(preconditioner_type_used));
}
- if (preconditioner_type == CLUSTER_JACOBI ||
- preconditioner_type == CLUSTER_TRIDIAGONAL) {
+ if (preconditioner_type_used == CLUSTER_JACOBI ||
+ preconditioner_type_used == CLUSTER_TRIDIAGONAL) {
StringAppendF(&report, "Visibility clustering%24s%25s\n",
VisibilityClusteringTypeToString(
visibility_clustering_type),
@@ -345,9 +802,7 @@ string Solver::Summary::FullReport() const {
};
bool Solver::Summary::IsSolutionUsable() const {
- return (termination_type == CONVERGENCE ||
- termination_type == NO_CONVERGENCE ||
- termination_type == USER_SUCCESS);
+ return internal::IsSolutionUsable(*this);
}
} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc
deleted file mode 100644
index 2bf6cd26212..00000000000
--- a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.cc
+++ /dev/null
@@ -1,1851 +0,0 @@
-// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 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: keir@google.com (Keir Mierle)
-
-#include "ceres/solver_impl.h"
-
-#include <cstdio>
-#include <iostream> // NOLINT
-#include <numeric>
-#include <string>
-#include "ceres/coordinate_descent_minimizer.h"
-#include "ceres/cxsparse.h"
-#include "ceres/evaluator.h"
-#include "ceres/gradient_checking_cost_function.h"
-#include "ceres/iteration_callback.h"
-#include "ceres/levenberg_marquardt_strategy.h"
-#include "ceres/line_search_minimizer.h"
-#include "ceres/linear_solver.h"
-#include "ceres/map_util.h"
-#include "ceres/minimizer.h"
-#include "ceres/ordered_groups.h"
-#include "ceres/parameter_block.h"
-#include "ceres/parameter_block_ordering.h"
-#include "ceres/problem.h"
-#include "ceres/problem_impl.h"
-#include "ceres/program.h"
-#include "ceres/residual_block.h"
-#include "ceres/stringprintf.h"
-#include "ceres/suitesparse.h"
-#include "ceres/trust_region_minimizer.h"
-#include "ceres/wall_time.h"
-
-namespace ceres {
-namespace internal {
-namespace {
-
-// Callback for updating the user's parameter blocks. Updates are only
-// done if the step is successful.
-class StateUpdatingCallback : public IterationCallback {
- public:
- StateUpdatingCallback(Program* program, double* parameters)
- : program_(program), parameters_(parameters) {}
-
- CallbackReturnType operator()(const IterationSummary& summary) {
- if (summary.step_is_successful) {
- program_->StateVectorToParameterBlocks(parameters_);
- program_->CopyParameterBlockStateToUserState();
- }
- return SOLVER_CONTINUE;
- }
-
- private:
- Program* program_;
- double* parameters_;
-};
-
-void SetSummaryFinalCost(Solver::Summary* summary) {
- summary->final_cost = summary->initial_cost;
- // We need the loop here, instead of just looking at the last
- // iteration because the minimizer maybe making non-monotonic steps.
- for (int i = 0; i < summary->iterations.size(); ++i) {
- const IterationSummary& iteration_summary = summary->iterations[i];
- summary->final_cost = min(iteration_summary.cost, summary->final_cost);
- }
-}
-
-// Callback for logging the state of the minimizer to STDERR or STDOUT
-// depending on the user's preferences and logging level.
-class TrustRegionLoggingCallback : public IterationCallback {
- public:
- explicit TrustRegionLoggingCallback(bool log_to_stdout)
- : log_to_stdout_(log_to_stdout) {}
-
- ~TrustRegionLoggingCallback() {}
-
- CallbackReturnType operator()(const IterationSummary& summary) {
- const char* kReportRowFormat =
- "% 4d: f:% 8e d:% 3.2e g:% 3.2e h:% 3.2e "
- "rho:% 3.2e mu:% 3.2e li:% 3d it:% 3.2e tt:% 3.2e";
- string output = StringPrintf(kReportRowFormat,
- summary.iteration,
- summary.cost,
- summary.cost_change,
- summary.gradient_max_norm,
- summary.step_norm,
- summary.relative_decrease,
- summary.trust_region_radius,
- summary.linear_solver_iterations,
- summary.iteration_time_in_seconds,
- summary.cumulative_time_in_seconds);
- if (log_to_stdout_) {
- cout << output << endl;
- } else {
- VLOG(1) << output;
- }
- return SOLVER_CONTINUE;
- }
-
- private:
- const bool log_to_stdout_;
-};
-
-// Callback for logging the state of the minimizer to STDERR or STDOUT
-// depending on the user's preferences and logging level.
-class LineSearchLoggingCallback : public IterationCallback {
- public:
- explicit LineSearchLoggingCallback(bool log_to_stdout)
- : log_to_stdout_(log_to_stdout) {}
-
- ~LineSearchLoggingCallback() {}
-
- CallbackReturnType operator()(const IterationSummary& summary) {
- const char* kReportRowFormat =
- "% 4d: f:% 8e d:% 3.2e g:% 3.2e h:% 3.2e "
- "s:% 3.2e e:% 3d it:% 3.2e tt:% 3.2e";
- string output = StringPrintf(kReportRowFormat,
- summary.iteration,
- summary.cost,
- summary.cost_change,
- summary.gradient_max_norm,
- summary.step_norm,
- summary.step_size,
- summary.line_search_function_evaluations,
- summary.iteration_time_in_seconds,
- summary.cumulative_time_in_seconds);
- if (log_to_stdout_) {
- cout << output << endl;
- } else {
- VLOG(1) << output;
- }
- return SOLVER_CONTINUE;
- }
-
- private:
- const bool log_to_stdout_;
-};
-
-
-// Basic callback to record the execution of the solver to a file for
-// offline analysis.
-class FileLoggingCallback : public IterationCallback {
- public:
- explicit FileLoggingCallback(const string& filename)
- : fptr_(NULL) {
- fptr_ = fopen(filename.c_str(), "w");
- CHECK_NOTNULL(fptr_);
- }
-
- virtual ~FileLoggingCallback() {
- if (fptr_ != NULL) {
- fclose(fptr_);
- }
- }
-
- virtual CallbackReturnType operator()(const IterationSummary& summary) {
- fprintf(fptr_,
- "%4d %e %e\n",
- summary.iteration,
- summary.cost,
- summary.cumulative_time_in_seconds);
- return SOLVER_CONTINUE;
- }
- private:
- FILE* fptr_;
-};
-
-// Iterate over each of the groups in order of their priority and fill
-// summary with their sizes.
-void SummarizeOrdering(ParameterBlockOrdering* ordering,
- vector<int>* summary) {
- CHECK_NOTNULL(summary)->clear();
- if (ordering == NULL) {
- return;
- }
-
- const map<int, set<double*> >& group_to_elements =
- ordering->group_to_elements();
- for (map<int, set<double*> >::const_iterator it = group_to_elements.begin();
- it != group_to_elements.end();
- ++it) {
- summary->push_back(it->second.size());
- }
-}
-
-void SummarizeGivenProgram(const Program& program, Solver::Summary* summary) {
- summary->num_parameter_blocks = program.NumParameterBlocks();
- summary->num_parameters = program.NumParameters();
- summary->num_effective_parameters = program.NumEffectiveParameters();
- summary->num_residual_blocks = program.NumResidualBlocks();
- summary->num_residuals = program.NumResiduals();
-}
-
-void SummarizeReducedProgram(const Program& program, Solver::Summary* summary) {
- summary->num_parameter_blocks_reduced = program.NumParameterBlocks();
- summary->num_parameters_reduced = program.NumParameters();
- summary->num_effective_parameters_reduced = program.NumEffectiveParameters();
- summary->num_residual_blocks_reduced = program.NumResidualBlocks();
- summary->num_residuals_reduced = program.NumResiduals();
-}
-
-bool ParameterBlocksAreFinite(const ProblemImpl* problem,
- string* message) {
- CHECK_NOTNULL(message);
- const Program& program = problem->program();
- const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
- for (int i = 0; i < parameter_blocks.size(); ++i) {
- const double* array = parameter_blocks[i]->user_state();
- const int size = parameter_blocks[i]->Size();
- const int invalid_index = FindInvalidValue(size, array);
- if (invalid_index != size) {
- *message = StringPrintf(
- "ParameterBlock: %p with size %d has at least one invalid value.\n"
- "First invalid value is at index: %d.\n"
- "Parameter block values: ",
- array, size, invalid_index);
- AppendArrayToString(size, array, message);
- return false;
- }
- }
- return true;
-}
-
-bool LineSearchOptionsAreValid(const Solver::Options& options,
- string* message) {
- // Validate values for configuration parameters supplied by user.
- if ((options.line_search_direction_type == ceres::BFGS ||
- options.line_search_direction_type == ceres::LBFGS) &&
- options.line_search_type != ceres::WOLFE) {
- *message =
- string("Invalid configuration: require line_search_type == "
- "ceres::WOLFE when using (L)BFGS to ensure that underlying "
- "assumptions are guaranteed to be satisfied.");
- return false;
- }
- if (options.max_lbfgs_rank <= 0) {
- *message =
- string("Invalid configuration: require max_lbfgs_rank > 0");
- return false;
- }
- if (options.min_line_search_step_size <= 0.0) {
- *message =
- "Invalid configuration: require min_line_search_step_size > 0.0.";
- return false;
- }
- if (options.line_search_sufficient_function_decrease <= 0.0) {
- *message =
- string("Invalid configuration: require ") +
- string("line_search_sufficient_function_decrease > 0.0.");
- return false;
- }
- if (options.max_line_search_step_contraction <= 0.0 ||
- options.max_line_search_step_contraction >= 1.0) {
- *message = string("Invalid configuration: require ") +
- string("0.0 < max_line_search_step_contraction < 1.0.");
- return false;
- }
- if (options.min_line_search_step_contraction <=
- options.max_line_search_step_contraction ||
- options.min_line_search_step_contraction > 1.0) {
- *message = string("Invalid configuration: require ") +
- string("max_line_search_step_contraction < ") +
- string("min_line_search_step_contraction <= 1.0.");
- return false;
- }
- // Warn user if they have requested BISECTION interpolation, but constraints
- // on max/min step size change during line search prevent bisection scaling
- // from occurring. Warn only, as this is likely a user mistake, but one which
- // does not prevent us from continuing.
- LOG_IF(WARNING,
- (options.line_search_interpolation_type == ceres::BISECTION &&
- (options.max_line_search_step_contraction > 0.5 ||
- options.min_line_search_step_contraction < 0.5)))
- << "Line search interpolation type is BISECTION, but specified "
- << "max_line_search_step_contraction: "
- << options.max_line_search_step_contraction << ", and "
- << "min_line_search_step_contraction: "
- << options.min_line_search_step_contraction
- << ", prevent bisection (0.5) scaling, continuing with solve regardless.";
- if (options.max_num_line_search_step_size_iterations <= 0) {
- *message = string("Invalid configuration: require ") +
- string("max_num_line_search_step_size_iterations > 0.");
- return false;
- }
- if (options.line_search_sufficient_curvature_decrease <=
- options.line_search_sufficient_function_decrease ||
- options.line_search_sufficient_curvature_decrease > 1.0) {
- *message = string("Invalid configuration: require ") +
- string("line_search_sufficient_function_decrease < ") +
- string("line_search_sufficient_curvature_decrease < 1.0.");
- return false;
- }
- if (options.max_line_search_step_expansion <= 1.0) {
- *message = string("Invalid configuration: require ") +
- string("max_line_search_step_expansion > 1.0.");
- return false;
- }
- return true;
-}
-
-// Returns true if the program has any non-constant parameter blocks
-// which have non-trivial bounds constraints.
-bool IsBoundsConstrained(const Program& program) {
- const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
- for (int i = 0; i < parameter_blocks.size(); ++i) {
- const ParameterBlock* parameter_block = parameter_blocks[i];
- if (parameter_block->IsConstant()) {
- continue;
- }
- const int size = parameter_block->Size();
- for (int j = 0; j < size; ++j) {
- const double lower_bound = parameter_block->LowerBoundForParameter(j);
- const double upper_bound = parameter_block->UpperBoundForParameter(j);
- if (lower_bound > -std::numeric_limits<double>::max() ||
- upper_bound < std::numeric_limits<double>::max()) {
- return true;
- }
- }
- }
- return false;
-}
-
-// Returns false, if the problem has any constant parameter blocks
-// which are not feasible, or any variable parameter blocks which have
-// a lower bound greater than or equal to the upper bound.
-bool ParameterBlocksAreFeasible(const ProblemImpl* problem, string* message) {
- CHECK_NOTNULL(message);
- const Program& program = problem->program();
- const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
- for (int i = 0; i < parameter_blocks.size(); ++i) {
- const ParameterBlock* parameter_block = parameter_blocks[i];
- const double* parameters = parameter_block->user_state();
- const int size = parameter_block->Size();
- if (parameter_block->IsConstant()) {
- // Constant parameter blocks must start in the feasible region
- // to ultimately produce a feasible solution, since Ceres cannot
- // change them.
- for (int j = 0; j < size; ++j) {
- const double lower_bound = parameter_block->LowerBoundForParameter(j);
- const double upper_bound = parameter_block->UpperBoundForParameter(j);
- if (parameters[j] < lower_bound || parameters[j] > upper_bound) {
- *message = StringPrintf(
- "ParameterBlock: %p with size %d has at least one infeasible "
- "value."
- "\nFirst infeasible value is at index: %d."
- "\nLower bound: %e, value: %e, upper bound: %e"
- "\nParameter block values: ",
- parameters, size, j, lower_bound, parameters[j], upper_bound);
- AppendArrayToString(size, parameters, message);
- return false;
- }
- }
- } else {
- // Variable parameter blocks must have non-empty feasible
- // regions, otherwise there is no way to produce a feasible
- // solution.
- for (int j = 0; j < size; ++j) {
- const double lower_bound = parameter_block->LowerBoundForParameter(j);
- const double upper_bound = parameter_block->UpperBoundForParameter(j);
- if (lower_bound >= upper_bound) {
- *message = StringPrintf(
- "ParameterBlock: %p with size %d has at least one infeasible "
- "bound."
- "\nFirst infeasible bound is at index: %d."
- "\nLower bound: %e, upper bound: %e"
- "\nParameter block values: ",
- parameters, size, j, lower_bound, upper_bound);
- AppendArrayToString(size, parameters, message);
- return false;
- }
- }
- }
- }
-
- return true;
-}
-
-
-} // namespace
-
-void SolverImpl::TrustRegionMinimize(
- const Solver::Options& options,
- Program* program,
- CoordinateDescentMinimizer* inner_iteration_minimizer,
- Evaluator* evaluator,
- LinearSolver* linear_solver,
- Solver::Summary* summary) {
- Minimizer::Options minimizer_options(options);
- minimizer_options.is_constrained = IsBoundsConstrained(*program);
-
- // The optimizer works on contiguous parameter vectors; allocate
- // some.
- Vector parameters(program->NumParameters());
-
- // Collect the discontiguous parameters into a contiguous state
- // vector.
- program->ParameterBlocksToStateVector(parameters.data());
-
- scoped_ptr<IterationCallback> file_logging_callback;
- if (!options.solver_log.empty()) {
- file_logging_callback.reset(new FileLoggingCallback(options.solver_log));
- minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
- file_logging_callback.get());
- }
-
- TrustRegionLoggingCallback logging_callback(
- options.minimizer_progress_to_stdout);
- if (options.logging_type != SILENT) {
- minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
- &logging_callback);
- }
-
- StateUpdatingCallback updating_callback(program, parameters.data());
- if (options.update_state_every_iteration) {
- // This must get pushed to the front of the callbacks so that it is run
- // before any of the user callbacks.
- minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
- &updating_callback);
- }
-
- minimizer_options.evaluator = evaluator;
- scoped_ptr<SparseMatrix> jacobian(evaluator->CreateJacobian());
-
- minimizer_options.jacobian = jacobian.get();
- minimizer_options.inner_iteration_minimizer = inner_iteration_minimizer;
-
- TrustRegionStrategy::Options trust_region_strategy_options;
- trust_region_strategy_options.linear_solver = linear_solver;
- trust_region_strategy_options.initial_radius =
- options.initial_trust_region_radius;
- trust_region_strategy_options.max_radius = options.max_trust_region_radius;
- trust_region_strategy_options.min_lm_diagonal = options.min_lm_diagonal;
- trust_region_strategy_options.max_lm_diagonal = options.max_lm_diagonal;
- trust_region_strategy_options.trust_region_strategy_type =
- options.trust_region_strategy_type;
- trust_region_strategy_options.dogleg_type = options.dogleg_type;
- scoped_ptr<TrustRegionStrategy> strategy(
- TrustRegionStrategy::Create(trust_region_strategy_options));
- minimizer_options.trust_region_strategy = strategy.get();
-
- TrustRegionMinimizer minimizer;
- double minimizer_start_time = WallTimeInSeconds();
- minimizer.Minimize(minimizer_options, parameters.data(), summary);
-
- // If the user aborted mid-optimization or the optimization
- // terminated because of a numerical failure, then do not update
- // user state.
- if (summary->termination_type != USER_FAILURE &&
- summary->termination_type != FAILURE) {
- program->StateVectorToParameterBlocks(parameters.data());
- program->CopyParameterBlockStateToUserState();
- }
-
- summary->minimizer_time_in_seconds =
- WallTimeInSeconds() - minimizer_start_time;
-}
-
-void SolverImpl::LineSearchMinimize(
- const Solver::Options& options,
- Program* program,
- Evaluator* evaluator,
- Solver::Summary* summary) {
- Minimizer::Options minimizer_options(options);
-
- // The optimizer works on contiguous parameter vectors; allocate some.
- Vector parameters(program->NumParameters());
-
- // Collect the discontiguous parameters into a contiguous state vector.
- program->ParameterBlocksToStateVector(parameters.data());
-
- // TODO(sameeragarwal): Add support for logging the configuration
- // and more detailed stats.
- scoped_ptr<IterationCallback> file_logging_callback;
- if (!options.solver_log.empty()) {
- file_logging_callback.reset(new FileLoggingCallback(options.solver_log));
- minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
- file_logging_callback.get());
- }
-
- LineSearchLoggingCallback logging_callback(
- options.minimizer_progress_to_stdout);
- if (options.logging_type != SILENT) {
- minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
- &logging_callback);
- }
-
- StateUpdatingCallback updating_callback(program, parameters.data());
- if (options.update_state_every_iteration) {
- // This must get pushed to the front of the callbacks so that it is run
- // before any of the user callbacks.
- minimizer_options.callbacks.insert(minimizer_options.callbacks.begin(),
- &updating_callback);
- }
-
- minimizer_options.evaluator = evaluator;
-
- LineSearchMinimizer minimizer;
- double minimizer_start_time = WallTimeInSeconds();
- minimizer.Minimize(minimizer_options, parameters.data(), summary);
-
- // If the user aborted mid-optimization or the optimization
- // terminated because of a numerical failure, then do not update
- // user state.
- if (summary->termination_type != USER_FAILURE &&
- summary->termination_type != FAILURE) {
- program->StateVectorToParameterBlocks(parameters.data());
- program->CopyParameterBlockStateToUserState();
- }
-
- summary->minimizer_time_in_seconds =
- WallTimeInSeconds() - minimizer_start_time;
-}
-
-void SolverImpl::Solve(const Solver::Options& options,
- ProblemImpl* problem_impl,
- Solver::Summary* summary) {
- VLOG(2) << "Initial problem: "
- << problem_impl->NumParameterBlocks()
- << " parameter blocks, "
- << problem_impl->NumParameters()
- << " parameters, "
- << problem_impl->NumResidualBlocks()
- << " residual blocks, "
- << problem_impl->NumResiduals()
- << " residuals.";
- *CHECK_NOTNULL(summary) = Solver::Summary();
- if (options.minimizer_type == TRUST_REGION) {
- TrustRegionSolve(options, problem_impl, summary);
- } else {
- LineSearchSolve(options, problem_impl, summary);
- }
-}
-
-void SolverImpl::TrustRegionSolve(const Solver::Options& original_options,
- ProblemImpl* original_problem_impl,
- Solver::Summary* summary) {
- EventLogger event_logger("TrustRegionSolve");
- double solver_start_time = WallTimeInSeconds();
-
- Program* original_program = original_problem_impl->mutable_program();
- ProblemImpl* problem_impl = original_problem_impl;
-
- summary->minimizer_type = TRUST_REGION;
-
- SummarizeGivenProgram(*original_program, summary);
- SummarizeOrdering(original_options.linear_solver_ordering.get(),
- &(summary->linear_solver_ordering_given));
- SummarizeOrdering(original_options.inner_iteration_ordering.get(),
- &(summary->inner_iteration_ordering_given));
-
- Solver::Options options(original_options);
-
-#ifndef CERES_USE_OPENMP
- if (options.num_threads > 1) {
- LOG(WARNING)
- << "OpenMP support is not compiled into this binary; "
- << "only options.num_threads=1 is supported. Switching "
- << "to single threaded mode.";
- options.num_threads = 1;
- }
- if (options.num_linear_solver_threads > 1) {
- LOG(WARNING)
- << "OpenMP support is not compiled into this binary; "
- << "only options.num_linear_solver_threads=1 is supported. Switching "
- << "to single threaded mode.";
- options.num_linear_solver_threads = 1;
- }
-#endif
-
- summary->num_threads_given = original_options.num_threads;
- summary->num_threads_used = options.num_threads;
-
- if (options.trust_region_minimizer_iterations_to_dump.size() > 0 &&
- options.trust_region_problem_dump_format_type != CONSOLE &&
- options.trust_region_problem_dump_directory.empty()) {
- summary->message =
- "Solver::Options::trust_region_problem_dump_directory is empty.";
- LOG(ERROR) << summary->message;
- return;
- }
-
- if (!ParameterBlocksAreFinite(problem_impl, &summary->message)) {
- LOG(ERROR) << "Terminating: " << summary->message;
- return;
- }
-
- if (!ParameterBlocksAreFeasible(problem_impl, &summary->message)) {
- LOG(ERROR) << "Terminating: " << summary->message;
- return;
- }
-
- event_logger.AddEvent("Init");
-
- original_program->SetParameterBlockStatePtrsToUserStatePtrs();
- event_logger.AddEvent("SetParameterBlockPtrs");
-
- // If the user requests gradient checking, construct a new
- // ProblemImpl by wrapping the CostFunctions of problem_impl inside
- // GradientCheckingCostFunction and replacing problem_impl with
- // gradient_checking_problem_impl.
- scoped_ptr<ProblemImpl> gradient_checking_problem_impl;
- if (options.check_gradients) {
- VLOG(1) << "Checking Gradients";
- gradient_checking_problem_impl.reset(
- CreateGradientCheckingProblemImpl(
- problem_impl,
- options.numeric_derivative_relative_step_size,
- options.gradient_check_relative_precision));
-
- // From here on, problem_impl will point to the gradient checking
- // version.
- problem_impl = gradient_checking_problem_impl.get();
- }
-
- if (options.linear_solver_ordering.get() != NULL) {
- if (!IsOrderingValid(options, problem_impl, &summary->message)) {
- LOG(ERROR) << summary->message;
- return;
- }
- event_logger.AddEvent("CheckOrdering");
- } else {
- options.linear_solver_ordering.reset(new ParameterBlockOrdering);
- const ProblemImpl::ParameterMap& parameter_map =
- problem_impl->parameter_map();
- for (ProblemImpl::ParameterMap::const_iterator it = parameter_map.begin();
- it != parameter_map.end();
- ++it) {
- options.linear_solver_ordering->AddElementToGroup(it->first, 0);
- }
- event_logger.AddEvent("ConstructOrdering");
- }
-
- // Create the three objects needed to minimize: the transformed program, the
- // evaluator, and the linear solver.
- scoped_ptr<Program> reduced_program(CreateReducedProgram(&options,
- problem_impl,
- &summary->fixed_cost,
- &summary->message));
-
- event_logger.AddEvent("CreateReducedProgram");
- if (reduced_program == NULL) {
- return;
- }
-
- SummarizeOrdering(options.linear_solver_ordering.get(),
- &(summary->linear_solver_ordering_used));
- SummarizeReducedProgram(*reduced_program, summary);
-
- if (summary->num_parameter_blocks_reduced == 0) {
- summary->preprocessor_time_in_seconds =
- WallTimeInSeconds() - solver_start_time;
-
- double post_process_start_time = WallTimeInSeconds();
-
- summary->message =
- "Terminating: Function tolerance reached. "
- "No non-constant parameter blocks found.";
- summary->termination_type = CONVERGENCE;
- VLOG_IF(1, options.logging_type != SILENT) << summary->message;
-
- summary->initial_cost = summary->fixed_cost;
- summary->final_cost = summary->fixed_cost;
-
- // Ensure the program state is set to the user parameters on the way out.
- original_program->SetParameterBlockStatePtrsToUserStatePtrs();
- original_program->SetParameterOffsetsAndIndex();
-
- summary->postprocessor_time_in_seconds =
- WallTimeInSeconds() - post_process_start_time;
- return;
- }
-
- scoped_ptr<LinearSolver>
- linear_solver(CreateLinearSolver(&options, &summary->message));
- event_logger.AddEvent("CreateLinearSolver");
- if (linear_solver == NULL) {
- return;
- }
-
- summary->linear_solver_type_given = original_options.linear_solver_type;
- summary->linear_solver_type_used = options.linear_solver_type;
-
- summary->preconditioner_type = options.preconditioner_type;
- summary->visibility_clustering_type = options.visibility_clustering_type;
-
- summary->num_linear_solver_threads_given =
- original_options.num_linear_solver_threads;
- summary->num_linear_solver_threads_used = options.num_linear_solver_threads;
-
- summary->dense_linear_algebra_library_type =
- options.dense_linear_algebra_library_type;
- summary->sparse_linear_algebra_library_type =
- options.sparse_linear_algebra_library_type;
-
- summary->trust_region_strategy_type = options.trust_region_strategy_type;
- summary->dogleg_type = options.dogleg_type;
-
- scoped_ptr<Evaluator> evaluator(CreateEvaluator(options,
- problem_impl->parameter_map(),
- reduced_program.get(),
- &summary->message));
-
- event_logger.AddEvent("CreateEvaluator");
-
- if (evaluator == NULL) {
- return;
- }
-
- scoped_ptr<CoordinateDescentMinimizer> inner_iteration_minimizer;
- if (options.use_inner_iterations) {
- if (reduced_program->parameter_blocks().size() < 2) {
- LOG(WARNING) << "Reduced problem only contains one parameter block."
- << "Disabling inner iterations.";
- } else {
- inner_iteration_minimizer.reset(
- CreateInnerIterationMinimizer(options,
- *reduced_program,
- problem_impl->parameter_map(),
- summary));
- if (inner_iteration_minimizer == NULL) {
- LOG(ERROR) << summary->message;
- return;
- }
- }
- }
- event_logger.AddEvent("CreateInnerIterationMinimizer");
-
- double minimizer_start_time = WallTimeInSeconds();
- summary->preprocessor_time_in_seconds =
- minimizer_start_time - solver_start_time;
-
- // Run the optimization.
- TrustRegionMinimize(options,
- reduced_program.get(),
- inner_iteration_minimizer.get(),
- evaluator.get(),
- linear_solver.get(),
- summary);
- event_logger.AddEvent("Minimize");
-
- double post_process_start_time = WallTimeInSeconds();
-
- SetSummaryFinalCost(summary);
-
- // Ensure the program state is set to the user parameters on the way
- // out.
- original_program->SetParameterBlockStatePtrsToUserStatePtrs();
- original_program->SetParameterOffsetsAndIndex();
-
- const map<string, double>& linear_solver_time_statistics =
- linear_solver->TimeStatistics();
- summary->linear_solver_time_in_seconds =
- FindWithDefault(linear_solver_time_statistics,
- "LinearSolver::Solve",
- 0.0);
-
- const map<string, double>& evaluator_time_statistics =
- evaluator->TimeStatistics();
-
- summary->residual_evaluation_time_in_seconds =
- FindWithDefault(evaluator_time_statistics, "Evaluator::Residual", 0.0);
- summary->jacobian_evaluation_time_in_seconds =
- FindWithDefault(evaluator_time_statistics, "Evaluator::Jacobian", 0.0);
-
- // Stick a fork in it, we're done.
- summary->postprocessor_time_in_seconds =
- WallTimeInSeconds() - post_process_start_time;
- event_logger.AddEvent("PostProcess");
-}
-
-void SolverImpl::LineSearchSolve(const Solver::Options& original_options,
- ProblemImpl* original_problem_impl,
- Solver::Summary* summary) {
- double solver_start_time = WallTimeInSeconds();
-
- Program* original_program = original_problem_impl->mutable_program();
- ProblemImpl* problem_impl = original_problem_impl;
-
- SummarizeGivenProgram(*original_program, summary);
- summary->minimizer_type = LINE_SEARCH;
- summary->line_search_direction_type =
- original_options.line_search_direction_type;
- summary->max_lbfgs_rank = original_options.max_lbfgs_rank;
- summary->line_search_type = original_options.line_search_type;
- summary->line_search_interpolation_type =
- original_options.line_search_interpolation_type;
- summary->nonlinear_conjugate_gradient_type =
- original_options.nonlinear_conjugate_gradient_type;
-
- if (!LineSearchOptionsAreValid(original_options, &summary->message)) {
- LOG(ERROR) << summary->message;
- return;
- }
-
- if (IsBoundsConstrained(problem_impl->program())) {
- summary->message = "LINE_SEARCH Minimizer does not support bounds.";
- LOG(ERROR) << "Terminating: " << summary->message;
- return;
- }
-
- Solver::Options options(original_options);
-
- // This ensures that we get a Block Jacobian Evaluator along with
- // none of the Schur nonsense. This file will have to be extensively
- // refactored to deal with the various bits of cleanups related to
- // line search.
- options.linear_solver_type = CGNR;
-
-
-#ifndef CERES_USE_OPENMP
- if (options.num_threads > 1) {
- LOG(WARNING)
- << "OpenMP support is not compiled into this binary; "
- << "only options.num_threads=1 is supported. Switching "
- << "to single threaded mode.";
- options.num_threads = 1;
- }
-#endif // CERES_USE_OPENMP
-
- summary->num_threads_given = original_options.num_threads;
- summary->num_threads_used = options.num_threads;
-
- if (!ParameterBlocksAreFinite(problem_impl, &summary->message)) {
- LOG(ERROR) << "Terminating: " << summary->message;
- return;
- }
-
- if (options.linear_solver_ordering.get() != NULL) {
- if (!IsOrderingValid(options, problem_impl, &summary->message)) {
- LOG(ERROR) << summary->message;
- return;
- }
- } else {
- options.linear_solver_ordering.reset(new ParameterBlockOrdering);
- const ProblemImpl::ParameterMap& parameter_map =
- problem_impl->parameter_map();
- for (ProblemImpl::ParameterMap::const_iterator it = parameter_map.begin();
- it != parameter_map.end();
- ++it) {
- options.linear_solver_ordering->AddElementToGroup(it->first, 0);
- }
- }
-
-
- original_program->SetParameterBlockStatePtrsToUserStatePtrs();
-
- // If the user requests gradient checking, construct a new
- // ProblemImpl by wrapping the CostFunctions of problem_impl inside
- // GradientCheckingCostFunction and replacing problem_impl with
- // gradient_checking_problem_impl.
- scoped_ptr<ProblemImpl> gradient_checking_problem_impl;
- if (options.check_gradients) {
- VLOG(1) << "Checking Gradients";
- gradient_checking_problem_impl.reset(
- CreateGradientCheckingProblemImpl(
- problem_impl,
- options.numeric_derivative_relative_step_size,
- options.gradient_check_relative_precision));
-
- // From here on, problem_impl will point to the gradient checking
- // version.
- problem_impl = gradient_checking_problem_impl.get();
- }
-
- // Create the three objects needed to minimize: the transformed program, the
- // evaluator, and the linear solver.
- scoped_ptr<Program> reduced_program(CreateReducedProgram(&options,
- problem_impl,
- &summary->fixed_cost,
- &summary->message));
- if (reduced_program == NULL) {
- return;
- }
-
- SummarizeReducedProgram(*reduced_program, summary);
- if (summary->num_parameter_blocks_reduced == 0) {
- summary->preprocessor_time_in_seconds =
- WallTimeInSeconds() - solver_start_time;
-
- summary->message =
- "Terminating: Function tolerance reached. "
- "No non-constant parameter blocks found.";
- summary->termination_type = CONVERGENCE;
- VLOG_IF(1, options.logging_type != SILENT) << summary->message;
-
- const double post_process_start_time = WallTimeInSeconds();
- SetSummaryFinalCost(summary);
-
- // Ensure the program state is set to the user parameters on the way out.
- original_program->SetParameterBlockStatePtrsToUserStatePtrs();
- original_program->SetParameterOffsetsAndIndex();
-
- summary->postprocessor_time_in_seconds =
- WallTimeInSeconds() - post_process_start_time;
- return;
- }
-
- scoped_ptr<Evaluator> evaluator(CreateEvaluator(options,
- problem_impl->parameter_map(),
- reduced_program.get(),
- &summary->message));
- if (evaluator == NULL) {
- return;
- }
-
- const double minimizer_start_time = WallTimeInSeconds();
- summary->preprocessor_time_in_seconds =
- minimizer_start_time - solver_start_time;
-
- // Run the optimization.
- LineSearchMinimize(options, reduced_program.get(), evaluator.get(), summary);
-
- const double post_process_start_time = WallTimeInSeconds();
-
- SetSummaryFinalCost(summary);
-
- // Ensure the program state is set to the user parameters on the way out.
- original_program->SetParameterBlockStatePtrsToUserStatePtrs();
- original_program->SetParameterOffsetsAndIndex();
-
- const map<string, double>& evaluator_time_statistics =
- evaluator->TimeStatistics();
-
- summary->residual_evaluation_time_in_seconds =
- FindWithDefault(evaluator_time_statistics, "Evaluator::Residual", 0.0);
- summary->jacobian_evaluation_time_in_seconds =
- FindWithDefault(evaluator_time_statistics, "Evaluator::Jacobian", 0.0);
-
- // Stick a fork in it, we're done.
- summary->postprocessor_time_in_seconds =
- WallTimeInSeconds() - post_process_start_time;
-}
-
-bool SolverImpl::IsOrderingValid(const Solver::Options& options,
- const ProblemImpl* problem_impl,
- string* error) {
- if (options.linear_solver_ordering->NumElements() !=
- problem_impl->NumParameterBlocks()) {
- *error = "Number of parameter blocks in user supplied ordering "
- "does not match the number of parameter blocks in the problem";
- return false;
- }
-
- const Program& program = problem_impl->program();
- const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
- for (vector<ParameterBlock*>::const_iterator it = parameter_blocks.begin();
- it != parameter_blocks.end();
- ++it) {
- if (!options.linear_solver_ordering
- ->IsMember(const_cast<double*>((*it)->user_state()))) {
- *error = "Problem contains a parameter block that is not in "
- "the user specified ordering.";
- return false;
- }
- }
-
- if (IsSchurType(options.linear_solver_type) &&
- options.linear_solver_ordering->NumGroups() > 1) {
- const vector<ResidualBlock*>& residual_blocks = program.residual_blocks();
- const set<double*>& e_blocks =
- options.linear_solver_ordering->group_to_elements().begin()->second;
- if (!IsParameterBlockSetIndependent(e_blocks, residual_blocks)) {
- *error = "The user requested the use of a Schur type solver. "
- "But the first elimination group in the ordering is not an "
- "independent set.";
- return false;
- }
- }
- return true;
-}
-
-bool SolverImpl::IsParameterBlockSetIndependent(
- const set<double*>& parameter_block_ptrs,
- const vector<ResidualBlock*>& residual_blocks) {
- // Loop over each residual block and ensure that no two parameter
- // blocks in the same residual block are part of
- // parameter_block_ptrs as that would violate the assumption that it
- // is an independent set in the Hessian matrix.
- for (vector<ResidualBlock*>::const_iterator it = residual_blocks.begin();
- it != residual_blocks.end();
- ++it) {
- ParameterBlock* const* parameter_blocks = (*it)->parameter_blocks();
- const int num_parameter_blocks = (*it)->NumParameterBlocks();
- int count = 0;
- for (int i = 0; i < num_parameter_blocks; ++i) {
- count += parameter_block_ptrs.count(
- parameter_blocks[i]->mutable_user_state());
- }
- if (count > 1) {
- return false;
- }
- }
- return true;
-}
-
-
-// Strips varying parameters and residuals, maintaining order, and updating
-// orderings.
-bool SolverImpl::RemoveFixedBlocksFromProgram(
- Program* program,
- ParameterBlockOrdering* linear_solver_ordering,
- ParameterBlockOrdering* inner_iteration_ordering,
- double* fixed_cost,
- string* error) {
- scoped_array<double> residual_block_evaluate_scratch;
- if (fixed_cost != NULL) {
- residual_block_evaluate_scratch.reset(
- new double[program->MaxScratchDoublesNeededForEvaluate()]);
- *fixed_cost = 0.0;
- }
-
- vector<ParameterBlock*>* parameter_blocks =
- program->mutable_parameter_blocks();
- vector<ResidualBlock*>* residual_blocks =
- program->mutable_residual_blocks();
-
- // Mark all the parameters as unused. Abuse the index member of the
- // parameter blocks for the marking.
- for (int i = 0; i < parameter_blocks->size(); ++i) {
- (*parameter_blocks)[i]->set_index(-1);
- }
-
- // Filter out residual that have all-constant parameters, and mark all the
- // parameter blocks that appear in residuals.
- int num_active_residual_blocks = 0;
- for (int i = 0; i < residual_blocks->size(); ++i) {
- ResidualBlock* residual_block = (*residual_blocks)[i];
- int num_parameter_blocks = residual_block->NumParameterBlocks();
-
- // Determine if the residual block is fixed, and also mark varying
- // parameters that appear in the residual block.
- bool all_constant = true;
- for (int k = 0; k < num_parameter_blocks; k++) {
- ParameterBlock* parameter_block = residual_block->parameter_blocks()[k];
- if (!parameter_block->IsConstant()) {
- all_constant = false;
- parameter_block->set_index(1);
- }
- }
-
- if (!all_constant) {
- (*residual_blocks)[num_active_residual_blocks++] = residual_block;
- } else if (fixed_cost != NULL) {
- // The residual is constant and will be removed, so its cost is
- // added to the variable fixed_cost.
- double cost = 0.0;
- if (!residual_block->Evaluate(true,
- &cost,
- NULL,
- NULL,
- residual_block_evaluate_scratch.get())) {
- *error = StringPrintf("Evaluation of the residual %d failed during "
- "removal of fixed residual blocks.", i);
- return false;
- }
- *fixed_cost += cost;
- }
- }
- residual_blocks->resize(num_active_residual_blocks);
-
- // Filter out unused or fixed parameter blocks, and update the
- // linear_solver_ordering and the inner_iteration_ordering (if
- // present).
- int num_active_parameter_blocks = 0;
- for (int i = 0; i < parameter_blocks->size(); ++i) {
- ParameterBlock* parameter_block = (*parameter_blocks)[i];
- if (parameter_block->index() == -1) {
- // Parameter block is constant.
- if (linear_solver_ordering != NULL) {
- linear_solver_ordering->Remove(parameter_block->mutable_user_state());
- }
-
- // It is not necessary that the inner iteration ordering contain
- // this parameter block. But calling Remove is safe, as it will
- // just return false.
- if (inner_iteration_ordering != NULL) {
- inner_iteration_ordering->Remove(parameter_block->mutable_user_state());
- }
- continue;
- }
-
- (*parameter_blocks)[num_active_parameter_blocks++] = parameter_block;
- }
- parameter_blocks->resize(num_active_parameter_blocks);
-
- if (!(((program->NumResidualBlocks() == 0) &&
- (program->NumParameterBlocks() == 0)) ||
- ((program->NumResidualBlocks() != 0) &&
- (program->NumParameterBlocks() != 0)))) {
- *error = "Congratulations, you found a bug in Ceres. Please report it.";
- return false;
- }
-
- return true;
-}
-
-Program* SolverImpl::CreateReducedProgram(Solver::Options* options,
- ProblemImpl* problem_impl,
- double* fixed_cost,
- string* error) {
- CHECK_NOTNULL(options->linear_solver_ordering.get());
- Program* original_program = problem_impl->mutable_program();
- scoped_ptr<Program> transformed_program(new Program(*original_program));
-
- ParameterBlockOrdering* linear_solver_ordering =
- options->linear_solver_ordering.get();
- const int min_group_id =
- linear_solver_ordering->group_to_elements().begin()->first;
- ParameterBlockOrdering* inner_iteration_ordering =
- options->inner_iteration_ordering.get();
- if (!RemoveFixedBlocksFromProgram(transformed_program.get(),
- linear_solver_ordering,
- inner_iteration_ordering,
- fixed_cost,
- error)) {
- return NULL;
- }
-
- VLOG(2) << "Reduced problem: "
- << transformed_program->NumParameterBlocks()
- << " parameter blocks, "
- << transformed_program->NumParameters()
- << " parameters, "
- << transformed_program->NumResidualBlocks()
- << " residual blocks, "
- << transformed_program->NumResiduals()
- << " residuals.";
-
- if (transformed_program->NumParameterBlocks() == 0) {
- LOG(WARNING) << "No varying parameter blocks to optimize; "
- << "bailing early.";
- return transformed_program.release();
- }
-
- if (IsSchurType(options->linear_solver_type) &&
- linear_solver_ordering->GroupSize(min_group_id) == 0) {
- // If the user requested the use of a Schur type solver, and
- // supplied a non-NULL linear_solver_ordering object with more than
- // one elimination group, then it can happen that after all the
- // parameter blocks which are fixed or unused have been removed from
- // the program and the ordering, there are no more parameter blocks
- // in the first elimination group.
- //
- // In such a case, the use of a Schur type solver is not possible,
- // as they assume there is at least one e_block. Thus, we
- // automatically switch to the closest solver to the one indicated
- // by the user.
- AlternateLinearSolverForSchurTypeLinearSolver(options);
- }
-
- if (IsSchurType(options->linear_solver_type)) {
- if (!ReorderProgramForSchurTypeLinearSolver(
- options->linear_solver_type,
- options->sparse_linear_algebra_library_type,
- problem_impl->parameter_map(),
- linear_solver_ordering,
- transformed_program.get(),
- error)) {
- return NULL;
- }
- return transformed_program.release();
- }
-
- if (options->linear_solver_type == SPARSE_NORMAL_CHOLESKY &&
- !options->dynamic_sparsity) {
- if (!ReorderProgramForSparseNormalCholesky(
- options->sparse_linear_algebra_library_type,
- linear_solver_ordering,
- transformed_program.get(),
- error)) {
- return NULL;
- }
-
- return transformed_program.release();
- }
-
- transformed_program->SetParameterOffsetsAndIndex();
- return transformed_program.release();
-}
-
-LinearSolver* SolverImpl::CreateLinearSolver(Solver::Options* options,
- string* error) {
- CHECK_NOTNULL(options);
- CHECK_NOTNULL(options->linear_solver_ordering.get());
- CHECK_NOTNULL(error);
-
- if (options->trust_region_strategy_type == DOGLEG) {
- if (options->linear_solver_type == ITERATIVE_SCHUR ||
- options->linear_solver_type == CGNR) {
- *error = "DOGLEG only supports exact factorization based linear "
- "solvers. If you want to use an iterative solver please "
- "use LEVENBERG_MARQUARDT as the trust_region_strategy_type";
- return NULL;
- }
- }
-
-#ifdef CERES_NO_LAPACK
- if (options->linear_solver_type == DENSE_NORMAL_CHOLESKY &&
- options->dense_linear_algebra_library_type == LAPACK) {
- *error = "Can't use DENSE_NORMAL_CHOLESKY with LAPACK because "
- "LAPACK was not enabled when Ceres was built.";
- return NULL;
- }
-
- if (options->linear_solver_type == DENSE_QR &&
- options->dense_linear_algebra_library_type == LAPACK) {
- *error = "Can't use DENSE_QR with LAPACK because "
- "LAPACK was not enabled when Ceres was built.";
- return NULL;
- }
-
- if (options->linear_solver_type == DENSE_SCHUR &&
- options->dense_linear_algebra_library_type == LAPACK) {
- *error = "Can't use DENSE_SCHUR with LAPACK because "
- "LAPACK was not enabled when Ceres was built.";
- return NULL;
- }
-#endif
-
-#ifdef CERES_NO_SUITESPARSE
- if (options->linear_solver_type == SPARSE_NORMAL_CHOLESKY &&
- options->sparse_linear_algebra_library_type == SUITE_SPARSE) {
- *error = "Can't use SPARSE_NORMAL_CHOLESKY with SUITESPARSE because "
- "SuiteSparse was not enabled when Ceres was built.";
- return NULL;
- }
-
- if (options->preconditioner_type == CLUSTER_JACOBI) {
- *error = "CLUSTER_JACOBI preconditioner not suppored. Please build Ceres "
- "with SuiteSparse support.";
- return NULL;
- }
-
- if (options->preconditioner_type == CLUSTER_TRIDIAGONAL) {
- *error = "CLUSTER_TRIDIAGONAL preconditioner not suppored. Please build "
- "Ceres with SuiteSparse support.";
- return NULL;
- }
-#endif
-
-#ifdef CERES_NO_CXSPARSE
- if (options->linear_solver_type == SPARSE_NORMAL_CHOLESKY &&
- options->sparse_linear_algebra_library_type == CX_SPARSE) {
- *error = "Can't use SPARSE_NORMAL_CHOLESKY with CXSPARSE because "
- "CXSparse was not enabled when Ceres was built.";
- return NULL;
- }
-#endif
-
-#if defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CXSPARSE)
- if (options->linear_solver_type == SPARSE_SCHUR) {
- *error = "Can't use SPARSE_SCHUR because neither SuiteSparse nor"
- "CXSparse was enabled when Ceres was compiled.";
- return NULL;
- }
-#endif
-
- if (options->max_linear_solver_iterations <= 0) {
- *error = "Solver::Options::max_linear_solver_iterations is not positive.";
- return NULL;
- }
- if (options->min_linear_solver_iterations <= 0) {
- *error = "Solver::Options::min_linear_solver_iterations is not positive.";
- return NULL;
- }
- if (options->min_linear_solver_iterations >
- options->max_linear_solver_iterations) {
- *error = "Solver::Options::min_linear_solver_iterations > "
- "Solver::Options::max_linear_solver_iterations.";
- return NULL;
- }
-
- LinearSolver::Options linear_solver_options;
- linear_solver_options.min_num_iterations =
- options->min_linear_solver_iterations;
- linear_solver_options.max_num_iterations =
- options->max_linear_solver_iterations;
- linear_solver_options.type = options->linear_solver_type;
- linear_solver_options.preconditioner_type = options->preconditioner_type;
- linear_solver_options.visibility_clustering_type =
- options->visibility_clustering_type;
- linear_solver_options.sparse_linear_algebra_library_type =
- options->sparse_linear_algebra_library_type;
- linear_solver_options.dense_linear_algebra_library_type =
- options->dense_linear_algebra_library_type;
- linear_solver_options.use_postordering = options->use_postordering;
- linear_solver_options.dynamic_sparsity = options->dynamic_sparsity;
-
- // Ignore user's postordering preferences and force it to be true if
- // cholmod_camd is not available. This ensures that the linear
- // solver does not assume that a fill-reducing pre-ordering has been
- // done.
-#if !defined(CERES_NO_SUITESPARSE) && defined(CERES_NO_CAMD)
- if (IsSchurType(linear_solver_options.type) &&
- options->sparse_linear_algebra_library_type == SUITE_SPARSE) {
- linear_solver_options.use_postordering = true;
- }
-#endif
-
- linear_solver_options.num_threads = options->num_linear_solver_threads;
- options->num_linear_solver_threads = linear_solver_options.num_threads;
-
- const map<int, set<double*> >& groups =
- options->linear_solver_ordering->group_to_elements();
- for (map<int, set<double*> >::const_iterator it = groups.begin();
- it != groups.end();
- ++it) {
- linear_solver_options.elimination_groups.push_back(it->second.size());
- }
- // Schur type solvers, expect at least two elimination groups. If
- // there is only one elimination group, then CreateReducedProgram
- // guarantees that this group only contains e_blocks. Thus we add a
- // dummy elimination group with zero blocks in it.
- if (IsSchurType(linear_solver_options.type) &&
- linear_solver_options.elimination_groups.size() == 1) {
- linear_solver_options.elimination_groups.push_back(0);
- }
-
- return LinearSolver::Create(linear_solver_options);
-}
-
-
-// Find the minimum index of any parameter block to the given residual.
-// Parameter blocks that have indices greater than num_eliminate_blocks are
-// considered to have an index equal to num_eliminate_blocks.
-static int MinParameterBlock(const ResidualBlock* residual_block,
- int num_eliminate_blocks) {
- int min_parameter_block_position = num_eliminate_blocks;
- for (int i = 0; i < residual_block->NumParameterBlocks(); ++i) {
- ParameterBlock* parameter_block = residual_block->parameter_blocks()[i];
- if (!parameter_block->IsConstant()) {
- CHECK_NE(parameter_block->index(), -1)
- << "Did you forget to call Program::SetParameterOffsetsAndIndex()? "
- << "This is a Ceres bug; please contact the developers!";
- min_parameter_block_position = std::min(parameter_block->index(),
- min_parameter_block_position);
- }
- }
- return min_parameter_block_position;
-}
-
-// Reorder the residuals for program, if necessary, so that the residuals
-// involving each E block occur together. This is a necessary condition for the
-// Schur eliminator, which works on these "row blocks" in the jacobian.
-bool SolverImpl::LexicographicallyOrderResidualBlocks(
- const int num_eliminate_blocks,
- Program* program,
- string* error) {
- CHECK_GE(num_eliminate_blocks, 1)
- << "Congratulations, you found a Ceres bug! Please report this error "
- << "to the developers.";
-
- // Create a histogram of the number of residuals for each E block. There is an
- // extra bucket at the end to catch all non-eliminated F blocks.
- vector<int> residual_blocks_per_e_block(num_eliminate_blocks + 1);
- vector<ResidualBlock*>* residual_blocks = program->mutable_residual_blocks();
- vector<int> min_position_per_residual(residual_blocks->size());
- for (int i = 0; i < residual_blocks->size(); ++i) {
- ResidualBlock* residual_block = (*residual_blocks)[i];
- int position = MinParameterBlock(residual_block, num_eliminate_blocks);
- min_position_per_residual[i] = position;
- DCHECK_LE(position, num_eliminate_blocks);
- residual_blocks_per_e_block[position]++;
- }
-
- // Run a cumulative sum on the histogram, to obtain offsets to the start of
- // each histogram bucket (where each bucket is for the residuals for that
- // E-block).
- vector<int> offsets(num_eliminate_blocks + 1);
- std::partial_sum(residual_blocks_per_e_block.begin(),
- residual_blocks_per_e_block.end(),
- offsets.begin());
- CHECK_EQ(offsets.back(), residual_blocks->size())
- << "Congratulations, you found a Ceres bug! Please report this error "
- << "to the developers.";
-
- CHECK(find(residual_blocks_per_e_block.begin(),
- residual_blocks_per_e_block.end() - 1, 0) !=
- residual_blocks_per_e_block.end())
- << "Congratulations, you found a Ceres bug! Please report this error "
- << "to the developers.";
-
- // Fill in each bucket with the residual blocks for its corresponding E block.
- // Each bucket is individually filled from the back of the bucket to the front
- // of the bucket. The filling order among the buckets is dictated by the
- // residual blocks. This loop uses the offsets as counters; subtracting one
- // from each offset as a residual block is placed in the bucket. When the
- // filling is finished, the offset pointerts should have shifted down one
- // entry (this is verified below).
- vector<ResidualBlock*> reordered_residual_blocks(
- (*residual_blocks).size(), static_cast<ResidualBlock*>(NULL));
- for (int i = 0; i < residual_blocks->size(); ++i) {
- int bucket = min_position_per_residual[i];
-
- // Decrement the cursor, which should now point at the next empty position.
- offsets[bucket]--;
-
- // Sanity.
- CHECK(reordered_residual_blocks[offsets[bucket]] == NULL)
- << "Congratulations, you found a Ceres bug! Please report this error "
- << "to the developers.";
-
- reordered_residual_blocks[offsets[bucket]] = (*residual_blocks)[i];
- }
-
- // Sanity check #1: The difference in bucket offsets should match the
- // histogram sizes.
- for (int i = 0; i < num_eliminate_blocks; ++i) {
- CHECK_EQ(residual_blocks_per_e_block[i], offsets[i + 1] - offsets[i])
- << "Congratulations, you found a Ceres bug! Please report this error "
- << "to the developers.";
- }
- // Sanity check #2: No NULL's left behind.
- for (int i = 0; i < reordered_residual_blocks.size(); ++i) {
- CHECK(reordered_residual_blocks[i] != NULL)
- << "Congratulations, you found a Ceres bug! Please report this error "
- << "to the developers.";
- }
-
- // Now that the residuals are collected by E block, swap them in place.
- swap(*program->mutable_residual_blocks(), reordered_residual_blocks);
- return true;
-}
-
-Evaluator* SolverImpl::CreateEvaluator(
- const Solver::Options& options,
- const ProblemImpl::ParameterMap& parameter_map,
- Program* program,
- string* error) {
- Evaluator::Options evaluator_options;
- evaluator_options.linear_solver_type = options.linear_solver_type;
- evaluator_options.num_eliminate_blocks =
- (options.linear_solver_ordering->NumGroups() > 0 &&
- IsSchurType(options.linear_solver_type))
- ? (options.linear_solver_ordering
- ->group_to_elements().begin()
- ->second.size())
- : 0;
- evaluator_options.num_threads = options.num_threads;
- evaluator_options.dynamic_sparsity = options.dynamic_sparsity;
- return Evaluator::Create(evaluator_options, program, error);
-}
-
-CoordinateDescentMinimizer* SolverImpl::CreateInnerIterationMinimizer(
- const Solver::Options& options,
- const Program& program,
- const ProblemImpl::ParameterMap& parameter_map,
- Solver::Summary* summary) {
- summary->inner_iterations_given = true;
-
- scoped_ptr<CoordinateDescentMinimizer> inner_iteration_minimizer(
- new CoordinateDescentMinimizer);
- scoped_ptr<ParameterBlockOrdering> inner_iteration_ordering;
- ParameterBlockOrdering* ordering_ptr = NULL;
-
- if (options.inner_iteration_ordering.get() == NULL) {
- // Find a recursive decomposition of the Hessian matrix as a set
- // of independent sets of decreasing size and invert it. This
- // seems to work better in practice, i.e., Cameras before
- // points.
- inner_iteration_ordering.reset(new ParameterBlockOrdering);
- ComputeRecursiveIndependentSetOrdering(program,
- inner_iteration_ordering.get());
- inner_iteration_ordering->Reverse();
- ordering_ptr = inner_iteration_ordering.get();
- } else {
- const map<int, set<double*> >& group_to_elements =
- options.inner_iteration_ordering->group_to_elements();
-
- // Iterate over each group and verify that it is an independent
- // set.
- map<int, set<double*> >::const_iterator it = group_to_elements.begin();
- for ( ; it != group_to_elements.end(); ++it) {
- if (!IsParameterBlockSetIndependent(it->second,
- program.residual_blocks())) {
- summary->message =
- StringPrintf("The user-provided "
- "parameter_blocks_for_inner_iterations does not "
- "form an independent set. Group Id: %d", it->first);
- return NULL;
- }
- }
- ordering_ptr = options.inner_iteration_ordering.get();
- }
-
- if (!inner_iteration_minimizer->Init(program,
- parameter_map,
- *ordering_ptr,
- &summary->message)) {
- return NULL;
- }
-
- summary->inner_iterations_used = true;
- summary->inner_iteration_time_in_seconds = 0.0;
- SummarizeOrdering(ordering_ptr, &(summary->inner_iteration_ordering_used));
- return inner_iteration_minimizer.release();
-}
-
-void SolverImpl::AlternateLinearSolverForSchurTypeLinearSolver(
- Solver::Options* options) {
- if (!IsSchurType(options->linear_solver_type)) {
- return;
- }
-
- string msg = "No e_blocks remaining. Switching from ";
- if (options->linear_solver_type == SPARSE_SCHUR) {
- options->linear_solver_type = SPARSE_NORMAL_CHOLESKY;
- msg += "SPARSE_SCHUR to SPARSE_NORMAL_CHOLESKY.";
- } else if (options->linear_solver_type == DENSE_SCHUR) {
- // TODO(sameeragarwal): This is probably not a great choice.
- // Ideally, we should have a DENSE_NORMAL_CHOLESKY, that can
- // take a BlockSparseMatrix as input.
- options->linear_solver_type = DENSE_QR;
- msg += "DENSE_SCHUR to DENSE_QR.";
- } else if (options->linear_solver_type == ITERATIVE_SCHUR) {
- options->linear_solver_type = CGNR;
- if (options->preconditioner_type != IDENTITY) {
- msg += StringPrintf("ITERATIVE_SCHUR with %s preconditioner "
- "to CGNR with JACOBI preconditioner.",
- PreconditionerTypeToString(
- options->preconditioner_type));
- // CGNR currently only supports the JACOBI preconditioner.
- options->preconditioner_type = JACOBI;
- } else {
- msg += "ITERATIVE_SCHUR with IDENTITY preconditioner"
- "to CGNR with IDENTITY preconditioner.";
- }
- }
- LOG(WARNING) << msg;
-}
-
-bool SolverImpl::ApplyUserOrdering(
- const ProblemImpl::ParameterMap& parameter_map,
- const ParameterBlockOrdering* parameter_block_ordering,
- Program* program,
- string* error) {
- const int num_parameter_blocks = program->NumParameterBlocks();
- if (parameter_block_ordering->NumElements() != num_parameter_blocks) {
- *error = StringPrintf("User specified ordering does not have the same "
- "number of parameters as the problem. The problem"
- "has %d blocks while the ordering has %d blocks.",
- num_parameter_blocks,
- parameter_block_ordering->NumElements());
- return false;
- }
-
- vector<ParameterBlock*>* parameter_blocks =
- program->mutable_parameter_blocks();
- parameter_blocks->clear();
-
- const map<int, set<double*> >& groups =
- parameter_block_ordering->group_to_elements();
-
- for (map<int, set<double*> >::const_iterator group_it = groups.begin();
- group_it != groups.end();
- ++group_it) {
- const set<double*>& group = group_it->second;
- for (set<double*>::const_iterator parameter_block_ptr_it = group.begin();
- parameter_block_ptr_it != group.end();
- ++parameter_block_ptr_it) {
- ProblemImpl::ParameterMap::const_iterator parameter_block_it =
- parameter_map.find(*parameter_block_ptr_it);
- if (parameter_block_it == parameter_map.end()) {
- *error = StringPrintf("User specified ordering contains a pointer "
- "to a double that is not a parameter block in "
- "the problem. The invalid double is in group: %d",
- group_it->first);
- return false;
- }
- parameter_blocks->push_back(parameter_block_it->second);
- }
- }
- return true;
-}
-
-
-TripletSparseMatrix* SolverImpl::CreateJacobianBlockSparsityTranspose(
- const Program* program) {
-
- // Matrix to store the block sparsity structure of the Jacobian.
- TripletSparseMatrix* tsm =
- new TripletSparseMatrix(program->NumParameterBlocks(),
- program->NumResidualBlocks(),
- 10 * program->NumResidualBlocks());
- int num_nonzeros = 0;
- int* rows = tsm->mutable_rows();
- int* cols = tsm->mutable_cols();
- double* values = tsm->mutable_values();
-
- const vector<ResidualBlock*>& residual_blocks = program->residual_blocks();
- for (int c = 0; c < residual_blocks.size(); ++c) {
- const ResidualBlock* residual_block = residual_blocks[c];
- const int num_parameter_blocks = residual_block->NumParameterBlocks();
- ParameterBlock* const* parameter_blocks =
- residual_block->parameter_blocks();
-
- for (int j = 0; j < num_parameter_blocks; ++j) {
- if (parameter_blocks[j]->IsConstant()) {
- continue;
- }
-
- // Re-size the matrix if needed.
- if (num_nonzeros >= tsm->max_num_nonzeros()) {
- tsm->set_num_nonzeros(num_nonzeros);
- tsm->Reserve(2 * num_nonzeros);
- rows = tsm->mutable_rows();
- cols = tsm->mutable_cols();
- values = tsm->mutable_values();
- }
- CHECK_LT(num_nonzeros, tsm->max_num_nonzeros());
-
- const int r = parameter_blocks[j]->index();
- rows[num_nonzeros] = r;
- cols[num_nonzeros] = c;
- values[num_nonzeros] = 1.0;
- ++num_nonzeros;
- }
- }
-
- tsm->set_num_nonzeros(num_nonzeros);
- return tsm;
-}
-
-bool SolverImpl::ReorderProgramForSchurTypeLinearSolver(
- const LinearSolverType linear_solver_type,
- const SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
- const ProblemImpl::ParameterMap& parameter_map,
- ParameterBlockOrdering* parameter_block_ordering,
- Program* program,
- string* error) {
- if (parameter_block_ordering->NumGroups() == 1) {
- // If the user supplied an parameter_block_ordering with just one
- // group, it is equivalent to the user supplying NULL as an
- // parameter_block_ordering. Ceres is completely free to choose the
- // parameter block ordering as it sees fit. For Schur type solvers,
- // this means that the user wishes for Ceres to identify the
- // e_blocks, which we do by computing a maximal independent set.
- vector<ParameterBlock*> schur_ordering;
- const int num_eliminate_blocks =
- ComputeStableSchurOrdering(*program, &schur_ordering);
-
- CHECK_EQ(schur_ordering.size(), program->NumParameterBlocks())
- << "Congratulations, you found a Ceres bug! Please report this error "
- << "to the developers.";
-
- // Update the parameter_block_ordering object.
- for (int i = 0; i < schur_ordering.size(); ++i) {
- double* parameter_block = schur_ordering[i]->mutable_user_state();
- const int group_id = (i < num_eliminate_blocks) ? 0 : 1;
- parameter_block_ordering->AddElementToGroup(parameter_block, group_id);
- }
-
- // We could call ApplyUserOrdering but this is cheaper and
- // simpler.
- swap(*program->mutable_parameter_blocks(), schur_ordering);
- } else {
- // The user provided an ordering with more than one elimination
- // group. Trust the user and apply the ordering.
- if (!ApplyUserOrdering(parameter_map,
- parameter_block_ordering,
- program,
- error)) {
- return false;
- }
- }
-
- // Pre-order the columns corresponding to the schur complement if
- // possible.
-#if !defined(CERES_NO_SUITESPARSE) && !defined(CERES_NO_CAMD)
- if (linear_solver_type == SPARSE_SCHUR &&
- sparse_linear_algebra_library_type == SUITE_SPARSE) {
- vector<int> constraints;
- vector<ParameterBlock*>& parameter_blocks =
- *(program->mutable_parameter_blocks());
-
- for (int i = 0; i < parameter_blocks.size(); ++i) {
- constraints.push_back(
- parameter_block_ordering->GroupId(
- parameter_blocks[i]->mutable_user_state()));
- }
-
- // Renumber the entries of constraints to be contiguous integers
- // as camd requires that the group ids be in the range [0,
- // parameter_blocks.size() - 1].
- SolverImpl::CompactifyArray(&constraints);
-
- // Set the offsets and index for CreateJacobianSparsityTranspose.
- program->SetParameterOffsetsAndIndex();
- // Compute a block sparse presentation of J'.
- scoped_ptr<TripletSparseMatrix> tsm_block_jacobian_transpose(
- SolverImpl::CreateJacobianBlockSparsityTranspose(program));
-
- SuiteSparse ss;
- cholmod_sparse* block_jacobian_transpose =
- ss.CreateSparseMatrix(tsm_block_jacobian_transpose.get());
-
- vector<int> ordering(parameter_blocks.size(), 0);
- ss.ConstrainedApproximateMinimumDegreeOrdering(block_jacobian_transpose,
- &constraints[0],
- &ordering[0]);
- ss.Free(block_jacobian_transpose);
-
- const vector<ParameterBlock*> parameter_blocks_copy(parameter_blocks);
- for (int i = 0; i < program->NumParameterBlocks(); ++i) {
- parameter_blocks[i] = parameter_blocks_copy[ordering[i]];
- }
- }
-#endif
-
- program->SetParameterOffsetsAndIndex();
- // Schur type solvers also require that their residual blocks be
- // lexicographically ordered.
- const int num_eliminate_blocks =
- parameter_block_ordering->group_to_elements().begin()->second.size();
- return LexicographicallyOrderResidualBlocks(num_eliminate_blocks,
- program,
- error);
-}
-
-bool SolverImpl::ReorderProgramForSparseNormalCholesky(
- const SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
- const ParameterBlockOrdering* parameter_block_ordering,
- Program* program,
- string* error) {
- // Set the offsets and index for CreateJacobianSparsityTranspose.
- program->SetParameterOffsetsAndIndex();
- // Compute a block sparse presentation of J'.
- scoped_ptr<TripletSparseMatrix> tsm_block_jacobian_transpose(
- SolverImpl::CreateJacobianBlockSparsityTranspose(program));
-
- vector<int> ordering(program->NumParameterBlocks(), 0);
- vector<ParameterBlock*>& parameter_blocks =
- *(program->mutable_parameter_blocks());
-
- if (sparse_linear_algebra_library_type == SUITE_SPARSE) {
-#ifdef CERES_NO_SUITESPARSE
- *error = "Can't use SPARSE_NORMAL_CHOLESKY with SUITE_SPARSE because "
- "SuiteSparse was not enabled when Ceres was built.";
- return false;
-#else
- SuiteSparse ss;
- cholmod_sparse* block_jacobian_transpose =
- ss.CreateSparseMatrix(tsm_block_jacobian_transpose.get());
-
-# ifdef CERES_NO_CAMD
- // No cholmod_camd, so ignore user's parameter_block_ordering and
- // use plain old AMD.
- ss.ApproximateMinimumDegreeOrdering(block_jacobian_transpose, &ordering[0]);
-# else
- if (parameter_block_ordering->NumGroups() > 1) {
- // If the user specified more than one elimination groups use them
- // to constrain the ordering.
- vector<int> constraints;
- for (int i = 0; i < parameter_blocks.size(); ++i) {
- constraints.push_back(
- parameter_block_ordering->GroupId(
- parameter_blocks[i]->mutable_user_state()));
- }
- ss.ConstrainedApproximateMinimumDegreeOrdering(
- block_jacobian_transpose,
- &constraints[0],
- &ordering[0]);
- } else {
- ss.ApproximateMinimumDegreeOrdering(block_jacobian_transpose,
- &ordering[0]);
- }
-# endif // CERES_NO_CAMD
-
- ss.Free(block_jacobian_transpose);
-#endif // CERES_NO_SUITESPARSE
-
- } else if (sparse_linear_algebra_library_type == CX_SPARSE) {
-#ifndef CERES_NO_CXSPARSE
-
- // CXSparse works with J'J instead of J'. So compute the block
- // sparsity for J'J and compute an approximate minimum degree
- // ordering.
- CXSparse cxsparse;
- cs_di* block_jacobian_transpose;
- block_jacobian_transpose =
- cxsparse.CreateSparseMatrix(tsm_block_jacobian_transpose.get());
- cs_di* block_jacobian = cxsparse.TransposeMatrix(block_jacobian_transpose);
- cs_di* block_hessian =
- cxsparse.MatrixMatrixMultiply(block_jacobian_transpose, block_jacobian);
- cxsparse.Free(block_jacobian);
- cxsparse.Free(block_jacobian_transpose);
-
- cxsparse.ApproximateMinimumDegreeOrdering(block_hessian, &ordering[0]);
- cxsparse.Free(block_hessian);
-#else // CERES_NO_CXSPARSE
- *error = "Can't use SPARSE_NORMAL_CHOLESKY with CX_SPARSE because "
- "CXSparse was not enabled when Ceres was built.";
- return false;
-#endif // CERES_NO_CXSPARSE
- } else {
- *error = "Unknown sparse linear algebra library.";
- return false;
- }
-
- // Apply ordering.
- const vector<ParameterBlock*> parameter_blocks_copy(parameter_blocks);
- for (int i = 0; i < program->NumParameterBlocks(); ++i) {
- parameter_blocks[i] = parameter_blocks_copy[ordering[i]];
- }
-
- program->SetParameterOffsetsAndIndex();
- return true;
-}
-
-void SolverImpl::CompactifyArray(vector<int>* array_ptr) {
- vector<int>& array = *array_ptr;
- const set<int> unique_group_ids(array.begin(), array.end());
- map<int, int> group_id_map;
- for (set<int>::const_iterator it = unique_group_ids.begin();
- it != unique_group_ids.end();
- ++it) {
- InsertOrDie(&group_id_map, *it, group_id_map.size());
- }
-
- for (int i = 0; i < array.size(); ++i) {
- array[i] = group_id_map[array[i]];
- }
-}
-
-} // namespace internal
-} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.h b/extern/libmv/third_party/ceres/internal/ceres/solver_impl.h
deleted file mode 100644
index 631add59bdb..00000000000
--- a/extern/libmv/third_party/ceres/internal/ceres/solver_impl.h
+++ /dev/null
@@ -1,228 +0,0 @@
-// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2010, 2011, 2012 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: keir@google.com (Keir Mierle)
-
-#ifndef CERES_INTERNAL_SOLVER_IMPL_H_
-#define CERES_INTERNAL_SOLVER_IMPL_H_
-
-#include <set>
-#include <string>
-#include <vector>
-#include "ceres/internal/port.h"
-#include "ceres/ordered_groups.h"
-#include "ceres/problem_impl.h"
-#include "ceres/solver.h"
-
-namespace ceres {
-namespace internal {
-
-class CoordinateDescentMinimizer;
-class Evaluator;
-class LinearSolver;
-class Program;
-class TripletSparseMatrix;
-
-class SolverImpl {
- public:
- // Mirrors the interface in solver.h, but exposes implementation
- // details for testing internally.
- static void Solve(const Solver::Options& options,
- ProblemImpl* problem_impl,
- Solver::Summary* summary);
-
- static void TrustRegionSolve(const Solver::Options& options,
- ProblemImpl* problem_impl,
- Solver::Summary* summary);
-
- // Run the TrustRegionMinimizer for the given evaluator and configuration.
- static void TrustRegionMinimize(
- const Solver::Options &options,
- Program* program,
- CoordinateDescentMinimizer* inner_iteration_minimizer,
- Evaluator* evaluator,
- LinearSolver* linear_solver,
- Solver::Summary* summary);
-
- static void LineSearchSolve(const Solver::Options& options,
- ProblemImpl* problem_impl,
- Solver::Summary* summary);
-
- // Run the LineSearchMinimizer for the given evaluator and configuration.
- static void LineSearchMinimize(const Solver::Options &options,
- Program* program,
- Evaluator* evaluator,
- Solver::Summary* summary);
-
- // Create the transformed Program, which has all the fixed blocks
- // and residuals eliminated, and in the case of automatic schur
- // ordering, has the E blocks first in the resulting program, with
- // options.num_eliminate_blocks set appropriately.
- //
- // If fixed_cost is not NULL, the residual blocks that are removed
- // are evaluated and the sum of their cost is returned in fixed_cost.
- static Program* CreateReducedProgram(Solver::Options* options,
- ProblemImpl* problem_impl,
- double* fixed_cost,
- string* message);
-
- // Create the appropriate linear solver, taking into account any
- // config changes decided by CreateTransformedProgram(). The
- // selected linear solver, which may be different from what the user
- // selected; consider the case that the remaining elimininated
- // blocks is zero after removing fixed blocks.
- static LinearSolver* CreateLinearSolver(Solver::Options* options,
- string* message);
-
- // Reorder the residuals for program, if necessary, so that the
- // residuals involving e block (i.e., the first num_eliminate_block
- // parameter blocks) occur together. This is a necessary condition
- // for the Schur eliminator.
- static bool LexicographicallyOrderResidualBlocks(
- const int num_eliminate_blocks,
- Program* program,
- string* message);
-
- // Create the appropriate evaluator for the transformed program.
- static Evaluator* CreateEvaluator(
- const Solver::Options& options,
- const ProblemImpl::ParameterMap& parameter_map,
- Program* program,
- string* message);
-
- // Remove the fixed or unused parameter blocks and residuals
- // depending only on fixed parameters from the program.
- //
- // If either linear_solver_ordering or inner_iteration_ordering are
- // not NULL, the constant parameter blocks are removed from them
- // too.
- //
- // If fixed_cost is not NULL, the residual blocks that are removed
- // are evaluated and the sum of their cost is returned in
- // fixed_cost.
- //
- // If a failure is encountered, the function returns false with a
- // description of the failure in message.
- static bool RemoveFixedBlocksFromProgram(
- Program* program,
- ParameterBlockOrdering* linear_solver_ordering,
- ParameterBlockOrdering* inner_iteration_ordering,
- double* fixed_cost,
- string* message);
-
- static bool IsOrderingValid(const Solver::Options& options,
- const ProblemImpl* problem_impl,
- string* message);
-
- static bool IsParameterBlockSetIndependent(
- const set<double*>& parameter_block_ptrs,
- const vector<ResidualBlock*>& residual_blocks);
-
- static CoordinateDescentMinimizer* CreateInnerIterationMinimizer(
- const Solver::Options& options,
- const Program& program,
- const ProblemImpl::ParameterMap& parameter_map,
- Solver::Summary* summary);
-
- // If the linear solver is of Schur type, then replace it with the
- // closest equivalent linear solver. This is done when the user
- // requested a Schur type solver but the problem structure makes it
- // impossible to use one.
- //
- // If the linear solver is not of Schur type, the function is a
- // no-op.
- static void AlternateLinearSolverForSchurTypeLinearSolver(
- Solver::Options* options);
-
- // Create a TripletSparseMatrix which contains the zero-one
- // structure corresponding to the block sparsity of the transpose of
- // the Jacobian matrix.
- //
- // Caller owns the result.
- static TripletSparseMatrix* CreateJacobianBlockSparsityTranspose(
- const Program* program);
-
- // Reorder the parameter blocks in program using the ordering
- static bool ApplyUserOrdering(
- const ProblemImpl::ParameterMap& parameter_map,
- const ParameterBlockOrdering* parameter_block_ordering,
- Program* program,
- string* message);
-
- // Sparse cholesky factorization routines when doing the sparse
- // cholesky factorization of the Jacobian matrix, reorders its
- // columns to reduce the fill-in. Compute this permutation and
- // re-order the parameter blocks.
- //
- // If the parameter_block_ordering contains more than one
- // elimination group and support for constrained fill-reducing
- // ordering is available in the sparse linear algebra library
- // (SuiteSparse version >= 4.2.0) then the fill reducing
- // ordering will take it into account, otherwise it will be ignored.
- static bool ReorderProgramForSparseNormalCholesky(
- const SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
- const ParameterBlockOrdering* parameter_block_ordering,
- Program* program,
- string* message);
-
- // Schur type solvers require that all parameter blocks eliminated
- // by the Schur eliminator occur before others and the residuals be
- // sorted in lexicographic order of their parameter blocks.
- //
- // If the parameter_block_ordering only contains one elimination
- // group then a maximal independent set is computed and used as the
- // first elimination group, otherwise the user's ordering is used.
- //
- // If the linear solver type is SPARSE_SCHUR and support for
- // constrained fill-reducing ordering is available in the sparse
- // linear algebra library (SuiteSparse version >= 4.2.0) then
- // columns of the schur complement matrix are ordered to reduce the
- // fill-in the Cholesky factorization.
- //
- // Upon return, ordering contains the parameter block ordering that
- // was used to order the program.
- static bool ReorderProgramForSchurTypeLinearSolver(
- const LinearSolverType linear_solver_type,
- const SparseLinearAlgebraLibraryType sparse_linear_algebra_library_type,
- const ProblemImpl::ParameterMap& parameter_map,
- ParameterBlockOrdering* parameter_block_ordering,
- Program* program,
- string* message);
-
- // array contains a list of (possibly repeating) non-negative
- // integers. Let us assume that we have constructed another array
- // `p` by sorting and uniqueing the entries of array.
- // CompactifyArray replaces each entry in "array" with its position
- // in `p`.
- static void CompactifyArray(vector<int>* array);
-};
-
-} // namespace internal
-} // namespace ceres
-
-#endif // CERES_INTERNAL_SOLVER_IMPL_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver_utils.cc b/extern/libmv/third_party/ceres/internal/ceres/solver_utils.cc
new file mode 100644
index 00000000000..bd304e7ac5d
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/solver_utils.cc
@@ -0,0 +1,78 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#include <string>
+
+#include "ceres/internal/port.h"
+#include "ceres/version.h"
+
+namespace ceres {
+namespace internal {
+
+string VersionString() {
+ string value = string(CERES_VERSION_STRING);
+
+#ifdef CERES_NO_LAPACK
+ value += "-no_lapack";
+#else
+ value += "-lapack";
+#endif
+
+#ifndef CERES_NO_SUITESPARSE
+ value += "-suitesparse";
+#endif
+
+#ifndef CERES_NO_CXSPARSE
+ value += "-cxsparse";
+#endif
+
+#ifdef CERES_USE_EIGEN_SPARSE
+ value += "-eigensparse";
+#endif
+
+#ifdef CERES_RESTRUCT_SCHUR_SPECIALIZATIONS
+ value += "-no_schur_specializations";
+#endif
+
+#ifdef CERES_USE_OPENMP
+ value += "-openmp";
+#else
+ value += "-no_openmp";
+#endif
+
+#ifdef CERES_NO_CUSTOM_BLAS
+ value += "-no_custom_blas";
+#endif
+
+ return value;
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/solver_utils.h b/extern/libmv/third_party/ceres/internal/ceres/solver_utils.h
new file mode 100644
index 00000000000..41c8a6e1292
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/solver_utils.h
@@ -0,0 +1,58 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#include <algorithm>
+#include <string>
+
+namespace ceres {
+namespace internal {
+
+template <typename SummaryType>
+bool IsSolutionUsable(const SummaryType& summary) {
+ return (summary.termination_type == CONVERGENCE ||
+ summary.termination_type == NO_CONVERGENCE ||
+ summary.termination_type == USER_SUCCESS);
+}
+
+template <typename SummaryType>
+void SetSummaryFinalCost(SummaryType* summary) {
+ summary->final_cost = summary->initial_cost;
+ // We need the loop here, instead of just looking at the last
+ // iteration because the minimizer maybe making non-monotonic steps.
+ for (int i = 0; i < summary->iterations.size(); ++i) {
+ const IterationSummary& iteration_summary = summary->iterations[i];
+ summary->final_cost = min(iteration_summary.cost, summary->final_cost);
+ }
+}
+
+string VersionString();
+
+} // namespace internal
+} // namespace ceres
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 cf5bb235b46..94f7e5803c4 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
@@ -28,11 +28,6 @@
//
// Author: sameeragarwal@google.com (Sameer Agarwal)
-// This include must come before any #ifndef check on Ceres compile options.
-#include "ceres/internal/port.h"
-
-#if !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARSE)
-
#include "ceres/sparse_normal_cholesky_solver.h"
#include <algorithm>
@@ -48,9 +43,67 @@
#include "ceres/triplet_sparse_matrix.h"
#include "ceres/types.h"
#include "ceres/wall_time.h"
+#include "Eigen/SparseCore"
+
+#ifdef CERES_USE_EIGEN_SPARSE
+#include "Eigen/SparseCholesky"
+#endif
namespace ceres {
namespace internal {
+namespace {
+
+#ifdef CERES_USE_EIGEN_SPARSE
+// A templated factorized and solve function, which allows us to use
+// the same code independent of whether a AMD or a Natural ordering is
+// used.
+template <typename SimplicialCholeskySolver>
+LinearSolver::Summary SimplicialLDLTSolve(
+ Eigen::MappedSparseMatrix<double, Eigen::ColMajor>& lhs,
+ const bool do_symbolic_analysis,
+ SimplicialCholeskySolver* solver,
+ double* rhs_and_solution,
+ EventLogger* event_logger) {
+ LinearSolver::Summary summary;
+ summary.num_iterations = 1;
+ summary.termination_type = LINEAR_SOLVER_SUCCESS;
+ summary.message = "Success.";
+
+ if (do_symbolic_analysis) {
+ solver->analyzePattern(lhs);
+ event_logger->AddEvent("Analyze");
+ if (solver->info() != Eigen::Success) {
+ summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
+ summary.message =
+ "Eigen failure. Unable to find symbolic factorization.";
+ return summary;
+ }
+ }
+
+ solver->factorize(lhs);
+ event_logger->AddEvent("Factorize");
+ if (solver->info() != Eigen::Success) {
+ summary.termination_type = LINEAR_SOLVER_FAILURE;
+ summary.message = "Eigen failure. Unable to find numeric factorization.";
+ return summary;
+ }
+
+ const Vector rhs = VectorRef(rhs_and_solution, lhs.cols());
+
+ VectorRef(rhs_and_solution, lhs.cols()) = solver->solve(rhs);
+ event_logger->AddEvent("Solve");
+ if (solver->info() != Eigen::Success) {
+ summary.termination_type = LINEAR_SOLVER_FAILURE;
+ summary.message = "Eigen failure. Unable to do triangular solve.";
+ return summary;
+ }
+
+ return summary;
+}
+
+#endif // CERES_USE_EIGEN_SPARSE
+
+} // namespace
SparseNormalCholeskySolver::SparseNormalCholeskySolver(
const LinearSolver::Options& options)
@@ -60,19 +113,15 @@ SparseNormalCholeskySolver::SparseNormalCholeskySolver(
}
void SparseNormalCholeskySolver::FreeFactorization() {
-#ifndef CERES_NO_SUITESPARSE
if (factor_ != NULL) {
ss_.Free(factor_);
factor_ = NULL;
}
-#endif // CERES_NO_SUITESPARSE
-#ifndef CERES_NO_CXSPARSE
if (cxsparse_factor_ != NULL) {
cxsparse_.Free(cxsparse_factor_);
cxsparse_factor_ = NULL;
}
-#endif // CERES_NO_CXSPARSE
}
SparseNormalCholeskySolver::~SparseNormalCholeskySolver() {
@@ -111,6 +160,9 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImpl(
case CX_SPARSE:
summary = SolveImplUsingCXSparse(A, per_solve_options, x);
break;
+ case EIGEN_SPARSE:
+ summary = SolveImplUsingEigen(A, per_solve_options, x);
+ break;
default:
LOG(FATAL) << "Unknown sparse linear algebra library : "
<< options_.sparse_linear_algebra_library_type;
@@ -123,11 +175,120 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImpl(
return summary;
}
-#ifndef CERES_NO_CXSPARSE
+LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingEigen(
+ CompressedRowSparseMatrix* A,
+ const LinearSolver::PerSolveOptions& per_solve_options,
+ double * rhs_and_solution) {
+#ifndef CERES_USE_EIGEN_SPARSE
+
+ LinearSolver::Summary summary;
+ summary.num_iterations = 0;
+ summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
+ summary.message =
+ "SPARSE_NORMAL_CHOLESKY cannot be used with EIGEN_SPARSE "
+ "because Ceres was not built with support for "
+ "Eigen's SimplicialLDLT decomposition. "
+ "This requires enabling building with -DEIGENSPARSE=ON.";
+ return summary;
+
+#else
+
+ EventLogger event_logger("SparseNormalCholeskySolver::Eigen::Solve");
+ // Compute the normal equations. J'J delta = J'f and solve them
+ // using a sparse Cholesky factorization. Notice that when compared
+ // to SuiteSparse we have to explicitly compute the normal equations
+ // before they can be factorized. CHOLMOD/SuiteSparse on the other
+ // hand can just work off of Jt to compute the Cholesky
+ // factorization of the normal equations.
+ //
+ // TODO(sameeragarwal): See note about how this maybe a bad idea for
+ // dynamic sparsity.
+ if (outer_product_.get() == NULL) {
+ outer_product_.reset(
+ CompressedRowSparseMatrix::CreateOuterProductMatrixAndProgram(
+ *A, &pattern_));
+ }
+
+ CompressedRowSparseMatrix::ComputeOuterProduct(
+ *A, pattern_, outer_product_.get());
+
+ // Map to an upper triangular column major matrix.
+ //
+ // outer_product_ is a compressed row sparse matrix and in lower
+ // triangular form, when mapped to a compressed column sparse
+ // matrix, it becomes an upper triangular matrix.
+ Eigen::MappedSparseMatrix<double, Eigen::ColMajor> AtA(
+ outer_product_->num_rows(),
+ outer_product_->num_rows(),
+ outer_product_->num_nonzeros(),
+ outer_product_->mutable_rows(),
+ outer_product_->mutable_cols(),
+ outer_product_->mutable_values());
+
+ // Dynamic sparsity means that we cannot depend on a static analysis
+ // of sparsity structure of the jacobian, so we compute a new
+ // symbolic factorization every time.
+ if (options_.dynamic_sparsity) {
+ amd_ldlt_.reset(NULL);
+ }
+
+ bool do_symbolic_analysis = false;
+
+ // If using post ordering or dynamic sparsity, or an old version of
+ // Eigen, we cannot depend on a preordered jacobian, so we work with
+ // a SimplicialLDLT decomposition with AMD ordering.
+ if (options_.use_postordering ||
+ options_.dynamic_sparsity ||
+ !EIGEN_VERSION_AT_LEAST(3, 2, 2)) {
+ if (amd_ldlt_.get() == NULL) {
+ amd_ldlt_.reset(new SimplicialLDLTWithAMDOrdering);
+ do_symbolic_analysis = true;
+ }
+
+ return SimplicialLDLTSolve(AtA,
+ do_symbolic_analysis,
+ amd_ldlt_.get(),
+ rhs_and_solution,
+ &event_logger);
+ }
+
+#if EIGEN_VERSION_AT_LEAST(3,2,2)
+ // The common case
+ if (natural_ldlt_.get() == NULL) {
+ natural_ldlt_.reset(new SimplicialLDLTWithNaturalOrdering);
+ do_symbolic_analysis = true;
+ }
+
+ return SimplicialLDLTSolve(AtA,
+ do_symbolic_analysis,
+ natural_ldlt_.get(),
+ rhs_and_solution,
+ &event_logger);
+#endif
+
+#endif // EIGEN_USE_EIGEN_SPARSE
+}
+
+
+
LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingCXSparse(
CompressedRowSparseMatrix* A,
const LinearSolver::PerSolveOptions& per_solve_options,
double * rhs_and_solution) {
+#ifdef CERES_NO_CXSPARSE
+
+ LinearSolver::Summary summary;
+ summary.num_iterations = 0;
+ summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
+ summary.message =
+ "SPARSE_NORMAL_CHOLESKY cannot be used with CX_SPARSE "
+ "because Ceres was not built with support for CXSparse. "
+ "This requires enabling building with -DCXSPARSE=ON.";
+
+ return summary;
+
+#else
+
EventLogger event_logger("SparseNormalCholeskySolver::CXSparse::Solve");
LinearSolver::Summary summary;
@@ -137,11 +298,14 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingCXSparse(
// Compute the normal equations. J'J delta = J'f and solve them
// using a sparse Cholesky factorization. Notice that when compared
- // to SuiteSparse we have to explicitly compute the transpose of Jt,
- // and then the normal equations before they can be
- // factorized. CHOLMOD/SuiteSparse on the other hand can just work
- // off of Jt to compute the Cholesky factorization of the normal
- // equations.
+ // to SuiteSparse we have to explicitly compute the normal equations
+ // before they can be factorized. CHOLMOD/SuiteSparse on the other
+ // hand can just work off of Jt to compute the Cholesky
+ // factorization of the normal equations.
+ //
+ // TODO(sameeragarwal): If dynamic sparsity is enabled, then this is
+ // not a good idea performance wise, since the jacobian has far too
+ // many entries and the program will go crazy with memory.
if (outer_product_.get() == NULL) {
outer_product_.reset(
CompressedRowSparseMatrix::CreateOuterProductMatrixAndProgram(
@@ -179,30 +343,35 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingCXSparse(
summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
summary.message =
"CXSparse failure. Unable to find symbolic factorization.";
- } else if (!cxsparse_.SolveCholesky(AtA, cxsparse_factor_, rhs_and_solution)) {
+ } else if (!cxsparse_.SolveCholesky(AtA,
+ cxsparse_factor_,
+ rhs_and_solution)) {
summary.termination_type = LINEAR_SOLVER_FAILURE;
+ summary.message = "CXSparse::SolveCholesky failed.";
}
event_logger.AddEvent("Solve");
return summary;
-}
-#else
-LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingCXSparse(
- CompressedRowSparseMatrix* A,
- const LinearSolver::PerSolveOptions& per_solve_options,
- double * rhs_and_solution) {
- LOG(FATAL) << "No CXSparse support in Ceres.";
-
- // Unreachable but MSVC does not know this.
- return LinearSolver::Summary();
-}
#endif
+}
-#ifndef CERES_NO_SUITESPARSE
LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
CompressedRowSparseMatrix* A,
const LinearSolver::PerSolveOptions& per_solve_options,
double * rhs_and_solution) {
+#ifdef CERES_NO_SUITESPARSE
+
+ LinearSolver::Summary summary;
+ summary.num_iterations = 0;
+ summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
+ summary.message =
+ "SPARSE_NORMAL_CHOLESKY cannot be used with SUITE_SPARSE "
+ "because Ceres was not built with support for SuiteSparse. "
+ "This requires enabling building with -DSUITESPARSE=ON.";
+ return summary;
+
+#else
+
EventLogger event_logger("SparseNormalCholeskySolver::SuiteSparse::Solve");
LinearSolver::Summary summary;
summary.termination_type = LINEAR_SOLVER_SUCCESS;
@@ -226,7 +395,8 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
if (options_.dynamic_sparsity) {
factor_ = ss_.AnalyzeCholesky(&lhs, &summary.message);
} else {
- factor_ = ss_.AnalyzeCholeskyWithNaturalOrdering(&lhs, &summary.message);
+ factor_ = ss_.AnalyzeCholeskyWithNaturalOrdering(&lhs,
+ &summary.message);
}
}
}
@@ -234,6 +404,8 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
if (factor_ == NULL) {
summary.termination_type = LINEAR_SOLVER_FATAL_ERROR;
+ // No need to set message as it has already been set by the
+ // symbolic analysis routines above.
return summary;
}
@@ -242,7 +414,9 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
return summary;
}
- cholmod_dense* rhs = ss_.CreateDenseVector(rhs_and_solution, num_cols, num_cols);
+ cholmod_dense* rhs = ss_.CreateDenseVector(rhs_and_solution,
+ num_cols,
+ num_cols);
cholmod_dense* solution = ss_.Solve(factor_, rhs, &summary.message);
event_logger.AddEvent("Solve");
@@ -251,25 +425,15 @@ LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
memcpy(rhs_and_solution, solution->x, num_cols * sizeof(*rhs_and_solution));
ss_.Free(solution);
} else {
+ // No need to set message as it has already been set by the
+ // numeric factorization routine above.
summary.termination_type = LINEAR_SOLVER_FAILURE;
}
event_logger.AddEvent("Teardown");
return summary;
-}
-#else
-LinearSolver::Summary SparseNormalCholeskySolver::SolveImplUsingSuiteSparse(
- CompressedRowSparseMatrix* A,
- const LinearSolver::PerSolveOptions& per_solve_options,
- double * rhs_and_solution) {
- LOG(FATAL) << "No SuiteSparse support in Ceres.";
-
- // Unreachable but MSVC does not know this.
- return LinearSolver::Summary();
-}
#endif
+}
} // namespace internal
} // namespace ceres
-
-#endif // !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARSE)
diff --git a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h
index ed777a118ae..12c05245075 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/sparse_normal_cholesky_solver.h
@@ -34,15 +34,19 @@
#ifndef CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
#define CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
+#include <vector>
+
// This include must come before any #ifndef check on Ceres compile options.
#include "ceres/internal/port.h"
-#if !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARSE)
-
-#include "ceres/cxsparse.h"
#include "ceres/internal/macros.h"
#include "ceres/linear_solver.h"
#include "ceres/suitesparse.h"
+#include "ceres/cxsparse.h"
+
+#ifdef CERES_USE_EIGEN_SPARSE
+#include "Eigen/SparseCholesky"
+#endif
namespace ceres {
namespace internal {
@@ -74,6 +78,12 @@ class SparseNormalCholeskySolver : public CompressedRowSparseMatrixSolver {
const LinearSolver::PerSolveOptions& options,
double* rhs_and_solution);
+ // Crashes if CERES_USE_EIGEN_SPARSE is not defined.
+ LinearSolver::Summary SolveImplUsingEigen(
+ CompressedRowSparseMatrix* A,
+ const LinearSolver::PerSolveOptions& options,
+ double* rhs_and_solution);
+
void FreeFactorization();
SuiteSparse ss_;
@@ -83,6 +93,32 @@ class SparseNormalCholeskySolver : public CompressedRowSparseMatrixSolver {
CXSparse cxsparse_;
// Cached factorization
cs_dis* cxsparse_factor_;
+
+#ifdef CERES_USE_EIGEN_SPARSE
+
+ // The preprocessor gymnastics here are dealing with the fact that
+ // before version 3.2.2, Eigen did not support a third template
+ // parameter to specify the ordering.
+#if EIGEN_VERSION_AT_LEAST(3,2,2)
+ typedef Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>, Eigen::Upper,
+ Eigen::NaturalOrdering<int> >
+ SimplicialLDLTWithNaturalOrdering;
+ scoped_ptr<SimplicialLDLTWithNaturalOrdering> natural_ldlt_;
+
+ typedef Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>, Eigen::Upper,
+ Eigen::AMDOrdering<int> >
+ SimplicialLDLTWithAMDOrdering;
+ scoped_ptr<SimplicialLDLTWithAMDOrdering> amd_ldlt_;
+
+#else
+ typedef Eigen::SimplicialLDLT<Eigen::SparseMatrix<double>, Eigen::Upper>
+ SimplicialLDLTWithAMDOrdering;
+
+ scoped_ptr<SimplicialLDLTWithAMDOrdering> amd_ldlt_;
+#endif
+
+#endif
+
scoped_ptr<CompressedRowSparseMatrix> outer_product_;
vector<int> pattern_;
const LinearSolver::Options options_;
@@ -92,5 +128,4 @@ class SparseNormalCholeskySolver : public CompressedRowSparseMatrixSolver {
} // namespace internal
} // namespace ceres
-#endif // !defined(CERES_NO_SUITESPARSE) || !defined(CERES_NO_CXSPARSE)
#endif // CERES_INTERNAL_SPARSE_NORMAL_CHOLESKY_SOLVER_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h
index 0a7ea97f2d7..baab8998b29 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/suitesparse.h
@@ -283,9 +283,24 @@ class SuiteSparse {
#else // CERES_NO_SUITESPARSE
-class SuiteSparse {};
typedef void cholmod_factor;
+class SuiteSparse {
+ public:
+ // Defining this static function even when SuiteSparse is not
+ // available, allows client code to check for the presence of CAMD
+ // without checking for the absence of the CERES_NO_CAMD symbol.
+ //
+ // This is safer because the symbol maybe missing due to a user
+ // accidently not including suitesparse.h in their code when
+ // checking for the symbol.
+ static bool IsConstrainedApproximateMinimumDegreeOrderingAvailable() {
+ return false;
+ }
+
+ void Free(void*) {};
+};
+
#endif // CERES_NO_SUITESPARSE
#endif // CERES_INTERNAL_SUITESPARSE_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.cc b/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.cc
index 4be561960c9..926bced6226 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/trust_region_minimizer.cc
@@ -1,5 +1,5 @@
// Ceres Solver - A fast non-linear least squares minimizer
-// Copyright 2012 Google Inc. All rights reserved.
+// Copyright 2014 Google Inc. All rights reserved.
// http://code.google.com/p/ceres-solver/
//
// Redistribution and use in source and binary forms, with or without
@@ -40,6 +40,7 @@
#include "Eigen/Core"
#include "ceres/array_utils.h"
+#include "ceres/coordinate_descent_minimizer.h"
#include "ceres/evaluator.h"
#include "ceres/file.h"
#include "ceres/internal/eigen.h"
@@ -128,9 +129,10 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
double iteration_start_time = start_time;
Init(options);
- Evaluator* evaluator = CHECK_NOTNULL(options_.evaluator);
- SparseMatrix* jacobian = CHECK_NOTNULL(options_.jacobian);
- TrustRegionStrategy* strategy = CHECK_NOTNULL(options_.trust_region_strategy);
+ Evaluator* evaluator = CHECK_NOTNULL(options_.evaluator.get());
+ SparseMatrix* jacobian = CHECK_NOTNULL(options_.jacobian.get());
+ TrustRegionStrategy* strategy =
+ CHECK_NOTNULL(options_.trust_region_strategy.get());
const bool is_not_silent = !options.is_silent;
@@ -253,7 +255,8 @@ void TrustRegionMinimizer::Minimize(const Minimizer::Options& options,
double candidate_cost = cost;
double accumulated_candidate_model_cost_change = 0.0;
int num_consecutive_invalid_steps = 0;
- bool inner_iterations_are_enabled = options.inner_iteration_minimizer != NULL;
+ bool inner_iterations_are_enabled =
+ options.inner_iteration_minimizer.get() != NULL;
while (true) {
bool inner_iterations_were_useful = false;
if (!RunCallbacks(options, iteration_summary, summary)) {
diff --git a/extern/libmv/third_party/ceres/internal/ceres/trust_region_preprocessor.cc b/extern/libmv/third_party/ceres/internal/ceres/trust_region_preprocessor.cc
new file mode 100644
index 00000000000..22ea1ec8c80
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/trust_region_preprocessor.cc
@@ -0,0 +1,358 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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)
+
+#include "ceres/trust_region_preprocessor.h"
+
+#include <numeric>
+#include <string>
+#include "ceres/callbacks.h"
+#include "ceres/evaluator.h"
+#include "ceres/linear_solver.h"
+#include "ceres/minimizer.h"
+#include "ceres/parameter_block.h"
+#include "ceres/preconditioner.h"
+#include "ceres/preprocessor.h"
+#include "ceres/problem_impl.h"
+#include "ceres/program.h"
+#include "ceres/reorder_program.h"
+#include "ceres/suitesparse.h"
+#include "ceres/trust_region_strategy.h"
+#include "ceres/wall_time.h"
+
+namespace ceres {
+namespace internal {
+namespace {
+
+ParameterBlockOrdering* CreateDefaultLinearSolverOrdering(
+ const Program& program) {
+ ParameterBlockOrdering* ordering = new ParameterBlockOrdering;
+ const vector<ParameterBlock*>& parameter_blocks = program.parameter_blocks();
+ for (int i = 0; i < parameter_blocks.size(); ++i) {
+ ordering->AddElementToGroup(
+ const_cast<double*>(parameter_blocks[i]->user_state()), 0);
+ }
+ return ordering;
+}
+
+// Check if all the user supplied values in the parameter blocks are
+// sane or not, and if the program is feasible or not.
+bool IsProgramValid(const Program& program, string* error) {
+ return (program.ParameterBlocksAreFinite(error) &&
+ program.IsFeasible(error));
+}
+
+void AlternateLinearSolverAndPreconditionerForSchurTypeLinearSolver(
+ Solver::Options* options) {
+ if (!IsSchurType(options->linear_solver_type)) {
+ return;
+ }
+
+ const LinearSolverType linear_solver_type_given = options->linear_solver_type;
+ const PreconditionerType preconditioner_type_given =
+ options->preconditioner_type;
+ options->linear_solver_type = LinearSolver::LinearSolverForZeroEBlocks(
+ linear_solver_type_given);
+
+ string message;
+ if (linear_solver_type_given == ITERATIVE_SCHUR) {
+ options->preconditioner_type = Preconditioner::PreconditionerForZeroEBlocks(
+ preconditioner_type_given);
+
+ message =
+ StringPrintf(
+ "No E blocks. Switching from %s(%s) to %s(%s).",
+ LinearSolverTypeToString(linear_solver_type_given),
+ PreconditionerTypeToString(preconditioner_type_given),
+ LinearSolverTypeToString(options->linear_solver_type),
+ PreconditionerTypeToString(options->preconditioner_type));
+ } else {
+ message =
+ StringPrintf(
+ "No E blocks. Switching from %s to %s.",
+ LinearSolverTypeToString(linear_solver_type_given),
+ LinearSolverTypeToString(options->linear_solver_type));
+ }
+
+ VLOG_IF(1, options->logging_type != SILENT) << message;
+}
+
+// For Schur type and SPARSE_NORMAL_CHOLESKY linear solvers, reorder
+// the program to reduce fill-in and increase cache coherency.
+bool ReorderProgram(PreprocessedProblem* pp) {
+ Solver::Options& options = pp->options;
+ if (IsSchurType(options.linear_solver_type)) {
+ return ReorderProgramForSchurTypeLinearSolver(
+ options.linear_solver_type,
+ options.sparse_linear_algebra_library_type,
+ pp->problem->parameter_map(),
+ options.linear_solver_ordering.get(),
+ pp->reduced_program.get(),
+ &pp->error);
+ }
+
+ if (options.linear_solver_type == SPARSE_NORMAL_CHOLESKY &&
+ !options.dynamic_sparsity) {
+ return ReorderProgramForSparseNormalCholesky(
+ options.sparse_linear_algebra_library_type,
+ *options.linear_solver_ordering,
+ pp->reduced_program.get(),
+ &pp->error);
+ }
+
+ return true;
+}
+
+// Configure and create a linear solver object. In doing so, if a
+// sparse direct factorization based linear solver is being used, then
+// find a fill reducing ordering and reorder the program as needed
+// too.
+bool SetupLinearSolver(PreprocessedProblem* pp) {
+ Solver::Options& options = pp->options;
+ if (options.linear_solver_ordering.get() == NULL) {
+ // If the user has not supplied a linear solver ordering, then we
+ // assume that they are giving all the freedom to us in choosing
+ // the best possible ordering. This intent can be indicated by
+ // putting all the parameter blocks in the same elimination group.
+ options.linear_solver_ordering.reset(
+ CreateDefaultLinearSolverOrdering(*pp->reduced_program));
+ } else {
+ // If the user supplied an ordering, then check if the first
+ // elimination group is still non-empty after the reduced problem
+ // has been constructed.
+ //
+ // This is important for Schur type linear solvers, where the
+ // first elimination group is special -- it needs to be an
+ // independent set.
+ //
+ // If the first elimination group is empty, then we cannot use the
+ // user's requested linear solver (and a preconditioner as the
+ // case may be) so we must use a different one.
+ ParameterBlockOrdering* ordering = options.linear_solver_ordering.get();
+ const int min_group_id = ordering->MinNonZeroGroup();
+ ordering->Remove(pp->removed_parameter_blocks);
+ if (IsSchurType(options.linear_solver_type) &&
+ min_group_id != ordering->MinNonZeroGroup()) {
+ AlternateLinearSolverAndPreconditionerForSchurTypeLinearSolver(
+ &options);
+ }
+ }
+
+ // Reorder the program to reduce fill in and improve cache coherency
+ // of the Jacobian.
+ if (!ReorderProgram(pp)) {
+ return false;
+ }
+
+ // Configure the linear solver.
+ pp->linear_solver_options = LinearSolver::Options();
+ pp->linear_solver_options.min_num_iterations =
+ options.min_linear_solver_iterations;
+ pp->linear_solver_options.max_num_iterations =
+ options.max_linear_solver_iterations;
+ pp->linear_solver_options.type = options.linear_solver_type;
+ pp->linear_solver_options.preconditioner_type = options.preconditioner_type;
+ pp->linear_solver_options.visibility_clustering_type =
+ options.visibility_clustering_type;
+ pp->linear_solver_options.sparse_linear_algebra_library_type =
+ options.sparse_linear_algebra_library_type;
+ pp->linear_solver_options.dense_linear_algebra_library_type =
+ options.dense_linear_algebra_library_type;
+ pp->linear_solver_options.use_explicit_schur_complement =
+ options.use_explicit_schur_complement;
+ pp->linear_solver_options.dynamic_sparsity = options.dynamic_sparsity;
+ pp->linear_solver_options.num_threads = options.num_linear_solver_threads;
+
+ // Ignore user's postordering preferences and force it to be true if
+ // cholmod_camd is not available. This ensures that the linear
+ // solver does not assume that a fill-reducing pre-ordering has been
+ // done.
+ pp->linear_solver_options.use_postordering = options.use_postordering;
+ if (options.linear_solver_type == SPARSE_SCHUR &&
+ options.sparse_linear_algebra_library_type == SUITE_SPARSE &&
+ !SuiteSparse::IsConstrainedApproximateMinimumDegreeOrderingAvailable()) {
+ pp->linear_solver_options.use_postordering = true;
+ }
+
+ OrderingToGroupSizes(options.linear_solver_ordering.get(),
+ &pp->linear_solver_options.elimination_groups);
+
+ // Schur type solvers expect at least two elimination groups. If
+ // there is only one elimination group, then it is guaranteed that
+ // this group only contains e_blocks. Thus we add a dummy
+ // elimination group with zero blocks in it.
+ if (IsSchurType(pp->linear_solver_options.type) &&
+ pp->linear_solver_options.elimination_groups.size() == 1) {
+ pp->linear_solver_options.elimination_groups.push_back(0);
+ }
+
+ pp->linear_solver.reset(LinearSolver::Create(pp->linear_solver_options));
+ return (pp->linear_solver.get() != NULL);
+}
+
+// Configure and create the evaluator.
+bool SetupEvaluator(PreprocessedProblem* pp) {
+ const Solver::Options& options = pp->options;
+ pp->evaluator_options = Evaluator::Options();
+ pp->evaluator_options.linear_solver_type = options.linear_solver_type;
+ pp->evaluator_options.num_eliminate_blocks = 0;
+ if (IsSchurType(options.linear_solver_type)) {
+ pp->evaluator_options.num_eliminate_blocks =
+ options
+ .linear_solver_ordering
+ ->group_to_elements().begin()
+ ->second.size();
+ }
+
+ pp->evaluator_options.num_threads = options.num_threads;
+ pp->evaluator_options.dynamic_sparsity = options.dynamic_sparsity;
+ pp->evaluator.reset(Evaluator::Create(pp->evaluator_options,
+ pp->reduced_program.get(),
+ &pp->error));
+
+ return (pp->evaluator.get() != NULL);
+}
+
+// If the user requested inner iterations, then find an inner
+// iteration ordering as needed and configure and create a
+// CoordinateDescentMinimizer object to perform the inner iterations.
+bool SetupInnerIterationMinimizer(PreprocessedProblem* pp) {
+ Solver::Options& options = pp->options;
+ if (!options.use_inner_iterations) {
+ return true;
+ }
+
+ // With just one parameter block, the outer iteration of the trust
+ // region method and inner iterations are doing exactly the same
+ // thing, and thus inner iterations are not needed.
+ if (pp->reduced_program->NumParameterBlocks() == 1) {
+ LOG(WARNING) << "Reduced problem only contains one parameter block."
+ << "Disabling inner iterations.";
+ return true;
+ }
+
+ if (options.inner_iteration_ordering.get() != NULL) {
+ // If the user supplied an ordering, then remove the set of
+ // inactive parameter blocks from it
+ options.inner_iteration_ordering->Remove(pp->removed_parameter_blocks);
+ if (options.inner_iteration_ordering->NumElements() == 0) {
+ LOG(WARNING) << "No remaining elements in the inner iteration ordering.";
+ return true;
+ }
+
+ // Validate the reduced ordering.
+ if (!CoordinateDescentMinimizer::IsOrderingValid(
+ *pp->reduced_program,
+ *options.inner_iteration_ordering,
+ &pp->error)) {
+ return false;
+ }
+ } else {
+ // The user did not supply an ordering, so create one.
+ options.inner_iteration_ordering.reset(
+ CoordinateDescentMinimizer::CreateOrdering(*pp->reduced_program));
+ }
+
+ pp->inner_iteration_minimizer.reset(new CoordinateDescentMinimizer);
+ return pp->inner_iteration_minimizer->Init(*pp->reduced_program,
+ pp->problem->parameter_map(),
+ *options.inner_iteration_ordering,
+ &pp->error);
+}
+
+// Configure and create a TrustRegionMinimizer object.
+void SetupMinimizerOptions(PreprocessedProblem* pp) {
+ const Solver::Options& options = pp->options;
+
+ SetupCommonMinimizerOptions(pp);
+ pp->minimizer_options.is_constrained =
+ pp->reduced_program->IsBoundsConstrained();
+ pp->minimizer_options.jacobian.reset(pp->evaluator->CreateJacobian());
+ pp->minimizer_options.inner_iteration_minimizer =
+ pp->inner_iteration_minimizer;
+
+ TrustRegionStrategy::Options strategy_options;
+ strategy_options.linear_solver = pp->linear_solver.get();
+ strategy_options.initial_radius =
+ options.initial_trust_region_radius;
+ strategy_options.max_radius = options.max_trust_region_radius;
+ strategy_options.min_lm_diagonal = options.min_lm_diagonal;
+ strategy_options.max_lm_diagonal = options.max_lm_diagonal;
+ strategy_options.trust_region_strategy_type =
+ options.trust_region_strategy_type;
+ strategy_options.dogleg_type = options.dogleg_type;
+ pp->minimizer_options.trust_region_strategy.reset(
+ CHECK_NOTNULL(TrustRegionStrategy::Create(strategy_options)));
+}
+
+} // namespace
+
+TrustRegionPreprocessor::~TrustRegionPreprocessor() {
+}
+
+bool TrustRegionPreprocessor::Preprocess(const Solver::Options& options,
+ ProblemImpl* problem,
+ PreprocessedProblem* pp) {
+ CHECK_NOTNULL(pp);
+ pp->options = options;
+ ChangeNumThreadsIfNeeded(&pp->options);
+
+ pp->problem = problem;
+ Program* program = problem->mutable_program();
+ if (!IsProgramValid(*program, &pp->error)) {
+ return false;
+ }
+
+ pp->reduced_program.reset(
+ program->CreateReducedProgram(&pp->removed_parameter_blocks,
+ &pp->fixed_cost,
+ &pp->error));
+
+ if (pp->reduced_program.get() == NULL) {
+ return false;
+ }
+
+ if (pp->reduced_program->NumParameterBlocks() == 0) {
+ // The reduced problem has no parameter or residual blocks. There
+ // is nothing more to do.
+ return true;
+ }
+
+ if (!SetupLinearSolver(pp) ||
+ !SetupEvaluator(pp) ||
+ !SetupInnerIterationMinimizer(pp)) {
+ return false;
+ }
+
+ SetupMinimizerOptions(pp);
+ return true;
+}
+
+} // namespace internal
+} // namespace ceres
diff --git a/extern/libmv/third_party/ceres/internal/ceres/trust_region_preprocessor.h b/extern/libmv/third_party/ceres/internal/ceres/trust_region_preprocessor.h
new file mode 100644
index 00000000000..ba70ff92e73
--- /dev/null
+++ b/extern/libmv/third_party/ceres/internal/ceres/trust_region_preprocessor.h
@@ -0,0 +1,50 @@
+// Ceres Solver - A fast non-linear least squares minimizer
+// Copyright 2014 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: sameragarwal@google.com (Sameer Agarwal)
+
+#ifndef CERES_INTERNAL_TRUST_REGION_PREPROCESSOR_H_
+#define CERES_INTERNAL_TRUST_REGION_PREPROCESSOR_H_
+
+#include "ceres/preprocessor.h"
+
+namespace ceres {
+namespace internal {
+
+class TrustRegionPreprocessor : public Preprocessor {
+ public:
+ virtual ~TrustRegionPreprocessor();
+ virtual bool Preprocess(const Solver::Options& options,
+ ProblemImpl* problem,
+ PreprocessedProblem* preprocessed_problem);
+};
+
+} // namespace internal
+} // namespace ceres
+
+#endif // CERES_INTERNAL_TRUST_REGION_PREPROCESSOR_H_
diff --git a/extern/libmv/third_party/ceres/internal/ceres/types.cc b/extern/libmv/third_party/ceres/internal/ceres/types.cc
index 5a344ea43d7..47102616ee8 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/types.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/types.cc
@@ -96,6 +96,7 @@ const char* SparseLinearAlgebraLibraryTypeToString(
switch (type) {
CASESTR(SUITE_SPARSE);
CASESTR(CX_SPARSE);
+ CASESTR(EIGEN_SPARSE);
default:
return "UNKNOWN";
}
@@ -107,6 +108,7 @@ bool StringToSparseLinearAlgebraLibraryType(
UpperCase(&value);
STRENUM(SUITE_SPARSE);
STRENUM(CX_SPARSE);
+ STRENUM(EIGEN_SPARSE);
return false;
}
@@ -240,7 +242,7 @@ const char* NonlinearConjugateGradientTypeToString(
NonlinearConjugateGradientType type) {
switch (type) {
CASESTR(FLETCHER_REEVES);
- CASESTR(POLAK_RIBIRERE);
+ CASESTR(POLAK_RIBIERE);
CASESTR(HESTENES_STIEFEL);
default:
return "UNKNOWN";
@@ -252,7 +254,7 @@ bool StringToNonlinearConjugateGradientType(
NonlinearConjugateGradientType* type) {
UpperCase(&value);
STRENUM(FLETCHER_REEVES);
- STRENUM(POLAK_RIBIRERE);
+ STRENUM(POLAK_RIBIERE);
STRENUM(HESTENES_STIEFEL);
return false;
}
@@ -261,8 +263,8 @@ const char* CovarianceAlgorithmTypeToString(
CovarianceAlgorithmType type) {
switch (type) {
CASESTR(DENSE_SVD);
- CASESTR(SPARSE_CHOLESKY);
- CASESTR(SPARSE_QR);
+ CASESTR(EIGEN_SPARSE_QR);
+ CASESTR(SUITE_SPARSE_QR);
default:
return "UNKNOWN";
}
@@ -273,8 +275,8 @@ bool StringToCovarianceAlgorithmType(
CovarianceAlgorithmType* type) {
UpperCase(&value);
STRENUM(DENSE_SVD);
- STRENUM(SPARSE_CHOLESKY);
- STRENUM(SPARSE_QR);
+ STRENUM(EIGEN_SPARSE_QR);
+ STRENUM(SUITE_SPARSE_QR);
return false;
}
diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility.cc b/extern/libmv/third_party/ceres/internal/ceres/visibility.cc
index b3ee185581f..da8beedc663 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/visibility.cc
+++ b/extern/libmv/third_party/ceres/internal/ceres/visibility.cc
@@ -76,7 +76,8 @@ void ComputeVisibility(const CompressedRowBlockStructure& block_structure,
}
}
-Graph<int>* CreateSchurComplementGraph(const vector<set<int> >& visibility) {
+WeightedGraph<int>* CreateSchurComplementGraph(
+ const vector<set<int> >& visibility) {
const time_t start_time = time(NULL);
// Compute the number of e_blocks/point blocks. Since the visibility
// set for each e_block/camera contains the set of e_blocks/points
@@ -122,7 +123,7 @@ Graph<int>* CreateSchurComplementGraph(const vector<set<int> >& visibility) {
}
}
- Graph<int>* graph = new Graph<int>();
+ WeightedGraph<int>* graph = new WeightedGraph<int>;
// Add vertices and initialize the pairs for self edges so that self
// edges are guaranteed. This is needed for the Canonical views
diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility.h b/extern/libmv/third_party/ceres/internal/ceres/visibility.h
index 5ddd3a56082..322efe9bea4 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/visibility.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/visibility.h
@@ -72,9 +72,10 @@ void ComputeVisibility(const CompressedRowBlockStructure& block_structure,
// matrix/Schur complement matrix obtained by eliminating the e_blocks
// from the normal equations.
//
-// Caller acquires ownership of the returned Graph pointer
+// Caller acquires ownership of the returned WeightedGraph pointer
// (heap-allocated).
-Graph<int>* CreateSchurComplementGraph(const vector<set<int> >& visibility);
+WeightedGraph<int>* CreateSchurComplementGraph(
+ const vector<set<int> >& visibility);
} // namespace internal
} // namespace ceres
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 695eedcc8d9..c7ed0493d8c 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
@@ -167,9 +167,9 @@ void VisibilityBasedPreconditioner::ComputeClusterTridiagonalSparsity(
// maximum spanning forest of this graph.
vector<set<int> > cluster_visibility;
ComputeClusterVisibility(visibility, &cluster_visibility);
- scoped_ptr<Graph<int> > cluster_graph(
+ scoped_ptr<WeightedGraph<int> > cluster_graph(
CHECK_NOTNULL(CreateClusterGraph(cluster_visibility)));
- scoped_ptr<Graph<int> > forest(
+ scoped_ptr<WeightedGraph<int> > forest(
CHECK_NOTNULL(Degree2MaximumSpanningForest(*cluster_graph)));
ForestToClusterPairs(*forest, &cluster_pairs_);
}
@@ -189,7 +189,7 @@ void VisibilityBasedPreconditioner::InitStorage(
// memberships for each camera block.
void VisibilityBasedPreconditioner::ClusterCameras(
const vector<set<int> >& visibility) {
- scoped_ptr<Graph<int> > schur_complement_graph(
+ scoped_ptr<WeightedGraph<int> > schur_complement_graph(
CHECK_NOTNULL(CreateSchurComplementGraph(visibility)));
HashMap<int, int> membership;
@@ -498,7 +498,7 @@ bool VisibilityBasedPreconditioner::IsBlockPairOffDiagonal(
// Convert a graph into a list of edges that includes self edges for
// each vertex.
void VisibilityBasedPreconditioner::ForestToClusterPairs(
- const Graph<int>& forest,
+ const WeightedGraph<int>& forest,
HashSet<pair<int, int> >* cluster_pairs) const {
CHECK_NOTNULL(cluster_pairs)->clear();
const HashSet<int>& vertices = forest.vertices();
@@ -541,9 +541,9 @@ void VisibilityBasedPreconditioner::ComputeClusterVisibility(
// Construct a graph whose vertices are the clusters, and the edge
// weights are the number of 3D points visible to cameras in both the
// vertices.
-Graph<int>* VisibilityBasedPreconditioner::CreateClusterGraph(
+WeightedGraph<int>* VisibilityBasedPreconditioner::CreateClusterGraph(
const vector<set<int> >& cluster_visibility) const {
- Graph<int>* cluster_graph = new Graph<int>;
+ WeightedGraph<int>* cluster_graph = new WeightedGraph<int>;
for (int i = 0; i < num_clusters_; ++i) {
cluster_graph->AddVertex(i);
diff --git a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h
index 70cea83bf56..2f6922dce54 100644
--- a/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h
+++ b/extern/libmv/third_party/ceres/internal/ceres/visibility_based_preconditioner.h
@@ -156,8 +156,9 @@ class VisibilityBasedPreconditioner : public BlockSparseMatrixPreconditioner {
vector<int>* membership_vector) const;
void ComputeClusterVisibility(const vector<set<int> >& visibility,
vector<set<int> >* cluster_visibility) const;
- Graph<int>* CreateClusterGraph(const vector<set<int> >& visibility) const;
- void ForestToClusterPairs(const Graph<int>& forest,
+ WeightedGraph<int>* CreateClusterGraph(
+ const vector<set<int> >& visibility) const;
+ void ForestToClusterPairs(const WeightedGraph<int>& forest,
HashSet<pair<int, int> >* cluster_pairs) const;
void ComputeBlockPairsInPreconditioner(const CompressedRowBlockStructure& bs);
bool IsBlockPairInPreconditioner(int block1, int block2) const;
diff --git a/extern/lzo/minilzo/README.LZO b/extern/lzo/minilzo/README.LZO
index 058eace70a0..83e10e352ff 100644
--- a/extern/lzo/minilzo/README.LZO
+++ b/extern/lzo/minilzo/README.LZO
@@ -6,8 +6,8 @@
Author : Markus Franz Xaver Johannes Oberhumer
<markus@oberhumer.com>
http://www.oberhumer.com/opensource/lzo/
- Version : 2.06
- Date : 12 Aug 2011
+ Version : 2.08
+ Date : 29 Jun 2014
I've created miniLZO for projects where it is inconvenient to
include (or require) the full LZO source code just because you
@@ -110,9 +110,8 @@
Appendix D: Copyright
---------------------
- LZO and miniLZO are Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
- Markus Franz Xaver Oberhumer <markus@oberhumer.com>.
+ LZO and miniLZO are Copyright (C) 1996-2014 Markus Franz Xaver Oberhumer
+ All Rights Reserved.
LZO and miniLZO are distributed under the terms of the GNU General
Public License (GPL). See the file COPYING.
diff --git a/extern/lzo/minilzo/lzoconf.h b/extern/lzo/minilzo/lzoconf.h
index 23c6ca93fcc..61be29c5dc2 100644
--- a/extern/lzo/minilzo/lzoconf.h
+++ b/extern/lzo/minilzo/lzoconf.h
@@ -2,22 +2,7 @@
This file is part of the LZO real-time data compression library.
- Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
@@ -44,9 +29,9 @@
#ifndef __LZOCONF_H_INCLUDED
#define __LZOCONF_H_INCLUDED 1
-#define LZO_VERSION 0x2060
-#define LZO_VERSION_STRING "2.06"
-#define LZO_VERSION_DATE "Aug 12 2011"
+#define LZO_VERSION 0x2080
+#define LZO_VERSION_STRING "2.08"
+#define LZO_VERSION_DATE "Jun 29 2014"
/* internal Autoconf configuration file - only used when building LZO */
#if defined(LZO_HAVE_CONFIG_H)
@@ -63,7 +48,7 @@
#if !defined(CHAR_BIT) || (CHAR_BIT != 8)
# error "invalid CHAR_BIT"
#endif
-#if !defined(UCHAR_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
+#if !defined(UCHAR_MAX) || !defined(USHRT_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX)
# error "check your compiler installation"
#endif
#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1)
@@ -85,14 +70,6 @@ extern "C" {
// some core defines
************************************************************************/
-#if !defined(LZO_UINT32_C)
-# if (UINT_MAX < LZO_0xffffffffL)
-# define LZO_UINT32_C(c) c ## UL
-# else
-# define LZO_UINT32_C(c) ((c) + 0U)
-# endif
-#endif
-
/* memory checkers */
#if !defined(__LZO_CHECKER)
# if defined(__BOUNDS_CHECKING_ON)
@@ -111,28 +88,31 @@ extern "C" {
// integral and pointer types
************************************************************************/
-/* lzo_uint should match size_t */
+/* lzo_uint must match size_t */
#if !defined(LZO_UINT_MAX)
-# if defined(LZO_ABI_LLP64) /* WIN64 */
-# if defined(LZO_OS_WIN64)
+# if (LZO_ABI_LLP64)
+# if (LZO_OS_WIN64)
typedef unsigned __int64 lzo_uint;
typedef __int64 lzo_int;
# else
- typedef unsigned long long lzo_uint;
- typedef long long lzo_int;
+ typedef lzo_ullong_t lzo_uint;
+ typedef lzo_llong_t lzo_int;
# endif
+# define LZO_SIZEOF_LZO_UINT 8
# define LZO_UINT_MAX 0xffffffffffffffffull
# define LZO_INT_MAX 9223372036854775807LL
# define LZO_INT_MIN (-1LL - LZO_INT_MAX)
-# elif defined(LZO_ABI_IP32L64) /* MIPS R5900 */
+# elif (LZO_ABI_IP32L64) /* MIPS R5900 */
typedef unsigned int lzo_uint;
typedef int lzo_int;
+# define LZO_SIZEOF_LZO_UINT LZO_SIZEOF_INT
# define LZO_UINT_MAX UINT_MAX
# define LZO_INT_MAX INT_MAX
# define LZO_INT_MIN INT_MIN
# elif (ULONG_MAX >= LZO_0xffffffffL)
typedef unsigned long lzo_uint;
typedef long lzo_int;
+# define LZO_SIZEOF_LZO_UINT LZO_SIZEOF_LONG
# define LZO_UINT_MAX ULONG_MAX
# define LZO_INT_MAX LONG_MAX
# define LZO_INT_MIN LONG_MIN
@@ -141,63 +121,22 @@ extern "C" {
# endif
#endif
-/* Integral types with 32 bits or more. */
-#if !defined(LZO_UINT32_MAX)
-# if (UINT_MAX >= LZO_0xffffffffL)
- typedef unsigned int lzo_uint32;
- typedef int lzo_int32;
-# define LZO_UINT32_MAX UINT_MAX
-# define LZO_INT32_MAX INT_MAX
-# define LZO_INT32_MIN INT_MIN
-# elif (ULONG_MAX >= LZO_0xffffffffL)
- typedef unsigned long lzo_uint32;
- typedef long lzo_int32;
-# define LZO_UINT32_MAX ULONG_MAX
-# define LZO_INT32_MAX LONG_MAX
-# define LZO_INT32_MIN LONG_MIN
-# else
-# error "lzo_uint32"
-# endif
-#endif
-
-/* Integral types with exactly 64 bits. */
-#if !defined(LZO_UINT64_MAX)
-# if (LZO_UINT_MAX >= LZO_0xffffffffL)
-# if ((((LZO_UINT_MAX) >> 31) >> 31) == 3)
-# define lzo_uint64 lzo_uint
-# define lzo_int64 lzo_int
-# define LZO_UINT64_MAX LZO_UINT_MAX
-# define LZO_INT64_MAX LZO_INT_MAX
-# define LZO_INT64_MIN LZO_INT_MIN
-# endif
-# elif (ULONG_MAX >= LZO_0xffffffffL)
-# if ((((ULONG_MAX) >> 31) >> 31) == 3)
- typedef unsigned long lzo_uint64;
- typedef long lzo_int64;
-# define LZO_UINT64_MAX ULONG_MAX
-# define LZO_INT64_MAX LONG_MAX
-# define LZO_INT64_MIN LONG_MIN
-# endif
-# endif
-#endif
-
-/* The larger type of lzo_uint and lzo_uint32. */
-#if (LZO_UINT_MAX >= LZO_UINT32_MAX)
+/* The larger type of lzo_uint and lzo_uint32_t. */
+#if (LZO_SIZEOF_LZO_UINT >= 4)
# define lzo_xint lzo_uint
#else
-# define lzo_xint lzo_uint32
+# define lzo_xint lzo_uint32_t
#endif
-/* Memory model that allows to access memory at offsets of lzo_uint. */
-#if !defined(__LZO_MMODEL)
-# if (LZO_UINT_MAX <= UINT_MAX)
-# define __LZO_MMODEL /*empty*/
-# elif defined(LZO_HAVE_MM_HUGE_PTR)
-# define __LZO_MMODEL_HUGE 1
-# define __LZO_MMODEL __huge
-# else
-# define __LZO_MMODEL /*empty*/
-# endif
+typedef int lzo_bool;
+
+/* sanity checks */
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == LZO_SIZEOF_LZO_UINT)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint))
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint32_t))
+
+#ifndef __LZO_MMODEL
+#define __LZO_MMODEL /*empty*/
#endif
/* no typedef here because of const-pointer issues */
@@ -206,21 +145,52 @@ extern "C" {
#define lzo_voidp void __LZO_MMODEL *
#define lzo_shortp short __LZO_MMODEL *
#define lzo_ushortp unsigned short __LZO_MMODEL *
-#define lzo_uint32p lzo_uint32 __LZO_MMODEL *
-#define lzo_int32p lzo_int32 __LZO_MMODEL *
-#if defined(LZO_UINT64_MAX)
-#define lzo_uint64p lzo_uint64 __LZO_MMODEL *
-#define lzo_int64p lzo_int64 __LZO_MMODEL *
-#endif
-#define lzo_uintp lzo_uint __LZO_MMODEL *
#define lzo_intp lzo_int __LZO_MMODEL *
+#define lzo_uintp lzo_uint __LZO_MMODEL *
#define lzo_xintp lzo_xint __LZO_MMODEL *
#define lzo_voidpp lzo_voidp __LZO_MMODEL *
#define lzo_bytepp lzo_bytep __LZO_MMODEL *
-/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */
-#define lzo_byte unsigned char __LZO_MMODEL
-typedef int lzo_bool;
+#define lzo_int8_tp lzo_int8_t __LZO_MMODEL *
+#define lzo_uint8_tp lzo_uint8_t __LZO_MMODEL *
+#define lzo_int16_tp lzo_int16_t __LZO_MMODEL *
+#define lzo_uint16_tp lzo_uint16_t __LZO_MMODEL *
+#define lzo_int32_tp lzo_int32_t __LZO_MMODEL *
+#define lzo_uint32_tp lzo_uint32_t __LZO_MMODEL *
+#if defined(lzo_int64_t)
+#define lzo_int64_tp lzo_int64_t __LZO_MMODEL *
+#define lzo_uint64_tp lzo_uint64_t __LZO_MMODEL *
+#endif
+
+/* Older LZO versions used to support ancient systems and memory models
+ * like 16-bit MSDOS with __huge pointers and Cray PVP, but these
+ * obsolete configurations are not supported any longer.
+ */
+#if defined(__LZO_MMODEL_HUGE)
+#error "__LZO_MMODEL_HUGE is unsupported"
+#endif
+#if (LZO_MM_PVP)
+#error "LZO_MM_PVP is unsupported"
+#endif
+#if (LZO_SIZEOF_INT < 4)
+#error "LZO_SIZEOF_INT < 4 is unsupported"
+#endif
+#if (__LZO_UINTPTR_T_IS_POINTER)
+#error "__LZO_UINTPTR_T_IS_POINTER is unsupported"
+#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) >= 4)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) >= 4)
+/* Strange configurations where sizeof(lzo_uint) != sizeof(size_t) should
+ * work but have not received much testing lately, so be strict here.
+ */
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(size_t))
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(ptrdiff_t))
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(lzo_uintptr_t))
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_uintptr_t))
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_uintptr_t))
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long *) == sizeof(lzo_uintptr_t))
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_voidp))
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_bytep))
/***********************************************************************
@@ -315,7 +285,7 @@ struct lzo_callback_t
/* a progress indicator callback function (set to 0 to disable) */
lzo_progress_func_t nprogress;
- /* NOTE: the first parameter "self" of the nalloc/nfree/nprogress
+ /* INFO: the first parameter "self" of the nalloc/nfree/nprogress
* callbacks points back to this struct, so you are free to store
* some extra info in the following variables. */
lzo_voidp user1;
@@ -343,6 +313,9 @@ struct lzo_callback_t
#define LZO_E_INPUT_NOT_CONSUMED (-8)
#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */
#define LZO_E_INVALID_ARGUMENT (-10)
+#define LZO_E_INVALID_ALIGNMENT (-11) /* pointer argument is not properly aligned */
+#define LZO_E_OUTPUT_NOT_CONSUMED (-12)
+#define LZO_E_INTERNAL_ERROR (-99)
#ifndef lzo_sizeof_dict_t
@@ -356,7 +329,7 @@ struct lzo_callback_t
* compiler's view of various types are consistent.
*/
#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\
- (int)sizeof(long),(int)sizeof(lzo_uint32),(int)sizeof(lzo_uint),\
+ (int)sizeof(long),(int)sizeof(lzo_uint32_t),(int)sizeof(lzo_uint),\
(int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\
(int)sizeof(lzo_callback_t))
LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int);
@@ -379,18 +352,22 @@ LZO_EXTERN(lzo_voidp)
lzo_memset(lzo_voidp buf, int c, lzo_uint len);
/* checksum functions */
-LZO_EXTERN(lzo_uint32)
- lzo_adler32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
-LZO_EXTERN(lzo_uint32)
- lzo_crc32(lzo_uint32 c, const lzo_bytep buf, lzo_uint len);
-LZO_EXTERN(const lzo_uint32p)
+LZO_EXTERN(lzo_uint32_t)
+ lzo_adler32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len);
+LZO_EXTERN(lzo_uint32_t)
+ lzo_crc32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len);
+LZO_EXTERN(const lzo_uint32_tp)
lzo_get_crc32_table(void);
/* misc. */
LZO_EXTERN(int) _lzo_config_check(void);
-typedef union { lzo_bytep p; lzo_uint u; } __lzo_pu_u;
-typedef union { lzo_bytep p; lzo_uint32 u32; } __lzo_pu32_u;
-typedef union { void *vp; lzo_bytep bp; lzo_uint u; lzo_uint32 u32; unsigned long l; } lzo_align_t;
+typedef union {
+ lzo_voidp a00; lzo_bytep a01; lzo_uint a02; lzo_xint a03; lzo_uintptr_t a04;
+ void *a05; unsigned char *a06; unsigned long a07; size_t a08; ptrdiff_t a09;
+#if defined(lzo_int64_t)
+ lzo_uint64_t a10;
+#endif
+} lzo_align_t;
/* align a char pointer on a boundary that is a multiple of 'size' */
LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
@@ -399,9 +376,30 @@ LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
/***********************************************************************
-// deprecated macros - only for backward compatibility with LZO v1.xx
+// deprecated macros - only for backward compatibility
************************************************************************/
+/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */
+#define lzo_byte unsigned char
+/* deprecated type names */
+#define lzo_int32 lzo_int32_t
+#define lzo_uint32 lzo_uint32_t
+#define lzo_int32p lzo_int32_t __LZO_MMODEL *
+#define lzo_uint32p lzo_uint32_t __LZO_MMODEL *
+#define LZO_INT32_MAX LZO_INT32_C(2147483647)
+#define LZO_UINT32_MAX LZO_UINT32_C(4294967295)
+#if defined(lzo_int64_t)
+#define lzo_int64 lzo_int64_t
+#define lzo_uint64 lzo_uint64_t
+#define lzo_int64p lzo_int64_t __LZO_MMODEL *
+#define lzo_uint64p lzo_uint64_t __LZO_MMODEL *
+#define LZO_INT64_MAX LZO_INT64_C(9223372036854775807)
+#define LZO_UINT64_MAX LZO_UINT64_C(18446744073709551615)
+#endif
+/* deprecated types */
+typedef union { lzo_bytep a; lzo_uint b; } __lzo_pu_u;
+typedef union { lzo_bytep a; lzo_uint32_t b; } __lzo_pu32_u;
+
#if defined(LZO_CFG_COMPAT)
#define __LZOCONF_H 1
@@ -443,4 +441,4 @@ LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size);
#endif /* already included */
-/* vim:set ts=4 et: */
+/* vim:set ts=4 sw=4 et: */
diff --git a/extern/lzo/minilzo/lzodefs.h b/extern/lzo/minilzo/lzodefs.h
index 0e40e332a8d..f4ae9487ebe 100644
--- a/extern/lzo/minilzo/lzodefs.h
+++ b/extern/lzo/minilzo/lzodefs.h
@@ -2,22 +2,7 @@
This file is part of the LZO real-time data compression library.
- Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
@@ -47,12 +32,6 @@
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
# define __CYGWIN__ __CYGWIN32__
#endif
-#if defined(__IBMCPP__) && !defined(__IBMC__)
-# define __IBMC__ __IBMCPP__
-#endif
-#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER)
-# define __INTEL_COMPILER __ICL
-#endif
#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE)
# define _ALL_SOURCE 1
#endif
@@ -61,19 +40,30 @@
# define __LONG_MAX__ 9223372036854775807L
# endif
#endif
-#if defined(__INTEL_COMPILER) && defined(__linux__)
+#if !defined(LZO_CFG_NO_DISABLE_WUNDEF)
+#if defined(__ARMCC_VERSION)
+# pragma diag_suppress 193
+#elif defined(__clang__) && defined(__clang_minor__)
+# pragma clang diagnostic ignored "-Wundef"
+#elif defined(__INTEL_COMPILER)
# pragma warning(disable: 193)
-#endif
-#if defined(__KEIL__) && defined(__C166__)
-# pragma warning disable = 322
-#elif 0 && defined(__C251__)
+#elif defined(__KEIL__) && defined(__C166__)
# pragma warning disable = 322
-#endif
-#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
-# if (_MSC_VER >= 1300)
+#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__PATHSCALE__)
+# if ((__GNUC__-0) >= 5 || ((__GNUC__-0) == 4 && (__GNUC_MINOR__-0) >= 2))
+# pragma GCC diagnostic ignored "-Wundef"
+# endif
+#elif defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
+# if ((_MSC_VER-0) >= 1300)
# pragma warning(disable: 4668)
# endif
#endif
+#endif
+#if 0 && defined(__POCC__) && defined(_WIN32)
+# if (__POCC__ >= 400)
+# pragma warn(disable: 2216)
+# endif
+#endif
#if 0 && defined(__WATCOMC__)
# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060)
# pragma warning 203 9
@@ -82,13 +72,29 @@
#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__)
# pragma option -h
#endif
+#if !(LZO_CFG_NO_DISABLE_WCRTNONSTDC)
+#ifndef _CRT_NONSTDC_NO_DEPRECATE
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+#endif
+#ifndef _CRT_NONSTDC_NO_WARNINGS
+#define _CRT_NONSTDC_NO_WARNINGS 1
+#endif
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS 1
+#endif
+#endif
#if 0
-#define LZO_0xffffL 0xfffful
-#define LZO_0xffffffffL 0xfffffffful
+#define LZO_0xffffUL 0xfffful
+#define LZO_0xffffffffUL 0xfffffffful
#else
-#define LZO_0xffffL 65535ul
-#define LZO_0xffffffffL 4294967295ul
+#define LZO_0xffffUL 65535ul
+#define LZO_0xffffffffUL 4294967295ul
#endif
+#define LZO_0xffffL LZO_0xffffUL
+#define LZO_0xffffffffL LZO_0xffffffffUL
#if (LZO_0xffffL == LZO_0xffffffffL)
# error "your preprocessor is broken 1"
#endif
@@ -103,6 +109,13 @@
# error "your preprocessor is broken 4"
#endif
#endif
+#if defined(__COUNTER__)
+# ifndef LZO_CFG_USE_COUNTER
+# define LZO_CFG_USE_COUNTER 1
+# endif
+#else
+# undef LZO_CFG_USE_COUNTER
+#endif
#if (UINT_MAX == LZO_0xffffL)
#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__)
# if !defined(MSDOS)
@@ -233,14 +246,31 @@
#endif
#define LZO_PP_STRINGIZE(x) #x
#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x)
+#define LZO_PP_CONCAT0() /*empty*/
+#define LZO_PP_CONCAT1(a) a
#define LZO_PP_CONCAT2(a,b) a ## b
#define LZO_PP_CONCAT3(a,b,c) a ## b ## c
#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d
#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
+#define LZO_PP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f
+#define LZO_PP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g
+#define LZO_PP_ECONCAT0() LZO_PP_CONCAT0()
+#define LZO_PP_ECONCAT1(a) LZO_PP_CONCAT1(a)
#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b)
#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c)
#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d)
#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e)
+#define LZO_PP_ECONCAT6(a,b,c,d,e,f) LZO_PP_CONCAT6(a,b,c,d,e,f)
+#define LZO_PP_ECONCAT7(a,b,c,d,e,f,g) LZO_PP_CONCAT7(a,b,c,d,e,f,g)
+#define LZO_PP_EMPTY /*empty*/
+#define LZO_PP_EMPTY0() /*empty*/
+#define LZO_PP_EMPTY1(a) /*empty*/
+#define LZO_PP_EMPTY2(a,b) /*empty*/
+#define LZO_PP_EMPTY3(a,b,c) /*empty*/
+#define LZO_PP_EMPTY4(a,b,c,d) /*empty*/
+#define LZO_PP_EMPTY5(a,b,c,d,e) /*empty*/
+#define LZO_PP_EMPTY6(a,b,c,d,e,f) /*empty*/
+#define LZO_PP_EMPTY7(a,b,c,d,e,f,g) /*empty*/
#if 1
#define LZO_CPP_STRINGIZE(x) #x
#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x)
@@ -248,12 +278,16 @@
#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c
#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d
#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
+#define LZO_CPP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f
+#define LZO_CPP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g
#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b)
#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c)
#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d)
#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e)
+#define LZO_CPP_ECONCAT6(a,b,c,d,e,f) LZO_CPP_CONCAT6(a,b,c,d,e,f)
+#define LZO_CPP_ECONCAT7(a,b,c,d,e,f,g) LZO_CPP_CONCAT7(a,b,c,d,e,f,g)
#endif
-#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o))
+#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-!!(b))) - (o)) << 1) + (o)*!!(b))
#if 1 && defined(__cplusplus)
# if !defined(__STDC_CONSTANT_MACROS)
# define __STDC_CONSTANT_MACROS 1
@@ -263,9 +297,13 @@
# endif
#endif
#if defined(__cplusplus)
-# define LZO_EXTERN_C extern "C"
+# define LZO_EXTERN_C extern "C"
+# define LZO_EXTERN_C_BEGIN extern "C" {
+# define LZO_EXTERN_C_END }
#else
-# define LZO_EXTERN_C extern
+# define LZO_EXTERN_C extern
+# define LZO_EXTERN_C_BEGIN /*empty*/
+# define LZO_EXTERN_C_END /*empty*/
#endif
#if !defined(__LZO_OS_OVERRIDE)
#if (LZO_OS_FREESTANDING)
@@ -366,12 +404,12 @@
#elif defined(__VMS)
# define LZO_OS_VMS 1
# define LZO_INFO_OS "vms"
-#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__))
+#elif (defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)
# define LZO_OS_CONSOLE 1
# define LZO_OS_CONSOLE_PS2 1
# define LZO_INFO_OS "console"
# define LZO_INFO_OS_CONSOLE "ps2"
-#elif (defined(__mips__) && defined(__psp__))
+#elif defined(__mips__) && defined(__psp__)
# define LZO_OS_CONSOLE 1
# define LZO_OS_CONSOLE_PSP 1
# define LZO_INFO_OS "console"
@@ -399,9 +437,18 @@
# elif defined(__linux__) || defined(__linux) || defined(__LINUX__)
# define LZO_OS_POSIX_LINUX 1
# define LZO_INFO_OS_POSIX "linux"
-# elif defined(__APPLE__) || defined(__MACOS__)
-# define LZO_OS_POSIX_MACOSX 1
-# define LZO_INFO_OS_POSIX "macosx"
+# elif defined(__APPLE__) && defined(__MACH__)
+# if ((__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__-0) >= 20000)
+# define LZO_OS_POSIX_DARWIN 1040
+# define LZO_INFO_OS_POSIX "darwin_iphone"
+# elif ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1040)
+# define LZO_OS_POSIX_DARWIN __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
+# define LZO_INFO_OS_POSIX "darwin"
+# else
+# define LZO_OS_POSIX_DARWIN 1
+# define LZO_INFO_OS_POSIX "darwin"
+# endif
+# define LZO_OS_POSIX_MACOSX LZO_OS_POSIX_DARWIN
# elif defined(__minix__) || defined(__minix)
# define LZO_OS_POSIX_MINIX 1
# define LZO_INFO_OS_POSIX "minix"
@@ -436,18 +483,18 @@
#endif
#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
# if (UINT_MAX != LZO_0xffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
# if (ULONG_MAX != LZO_0xffffffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
#endif
#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64)
# if (UINT_MAX != LZO_0xffffffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
# if (ULONG_MAX != LZO_0xffffffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
#endif
#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__)
@@ -463,59 +510,65 @@
# define LZO_INFO_CC "sdcc"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC)
#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__)
-# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__)
+# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + (__PATHCC_MINOR__-0) * 0x100 + (__PATHCC_PATCHLEVEL__-0))
# define LZO_INFO_CC "Pathscale C"
# define LZO_INFO_CCVER __PATHSCALE__
-#elif defined(__INTEL_COMPILER)
-# define LZO_CC_INTELC 1
+# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# define LZO_CC_PATHSCALE_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
+# endif
+#elif defined(__INTEL_COMPILER) && ((__INTEL_COMPILER-0) > 0)
+# define LZO_CC_INTELC __INTEL_COMPILER
# define LZO_INFO_CC "Intel C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER)
-# if defined(_WIN32) || defined(_WIN64)
-# define LZO_CC_SYNTAX_MSC 1
-# else
-# define LZO_CC_SYNTAX_GNUC 1
+# if defined(_MSC_VER) && ((_MSC_VER-0) > 0)
+# define LZO_CC_INTELC_MSC _MSC_VER
+# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# define LZO_CC_INTELC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
# endif
#elif defined(__POCC__) && defined(_WIN32)
# define LZO_CC_PELLESC 1
# define LZO_INFO_CC "Pelles C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__)
-#elif defined(__clang__) && defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
# if defined(__GNUC_PATCHLEVEL__)
-# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
# else
-# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100)
# endif
+# define LZO_CC_ARMCC __ARMCC_VERSION
+# define LZO_INFO_CC "ARM C Compiler"
+# define LZO_INFO_CCVER __VERSION__
+#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__)
# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
-# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__)
+# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0))
# else
-# define LZO_CC_CLANG_CLANG 0x010000L
+# define LZO_CC_CLANG 0x010000L
+# endif
+# if defined(_MSC_VER) && ((_MSC_VER-0) > 0)
+# define LZO_CC_CLANG_MSC _MSC_VER
+# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
# endif
-# define LZO_CC_CLANG LZO_CC_CLANG_GNUC
# define LZO_INFO_CC "clang"
# define LZO_INFO_CCVER __VERSION__
#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
# if defined(__GNUC_PATCHLEVEL__)
-# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
# else
-# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100)
# endif
# define LZO_CC_LLVM LZO_CC_LLVM_GNUC
# define LZO_INFO_CC "llvm-gcc"
# define LZO_INFO_CCVER __VERSION__
-#elif defined(__GNUC__) && defined(__VERSION__)
-# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
-# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
-# elif defined(__GNUC_MINOR__)
-# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
-# else
-# define LZO_CC_GNUC (__GNUC__ * 0x10000L)
-# endif
-# define LZO_INFO_CC "gcc"
-# define LZO_INFO_CCVER __VERSION__
#elif defined(__ACK__) && defined(_ACK)
# define LZO_CC_ACK 1
# define LZO_INFO_CC "Amsterdam Compiler Kit C"
# define LZO_INFO_CCVER "unknown"
+#elif defined(__ARMCC_VERSION) && !defined(__GNUC__)
+# define LZO_CC_ARMCC __ARMCC_VERSION
+# define LZO_CC_ARMCC_ARMCC __ARMCC_VERSION
+# define LZO_INFO_CC "ARM C Compiler"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ARMCC_VERSION)
#elif defined(__AZTEC_C__)
# define LZO_CC_AZTECC 1
# define LZO_INFO_CC "Aztec C"
@@ -540,10 +593,23 @@
# define LZO_CC_DECC 1
# define LZO_INFO_CC "DEC C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC)
+#elif (defined(__ghs) || defined(__ghs__)) && defined(__GHS_VERSION_NUMBER) && ((__GHS_VERSION_NUMBER-0) > 0)
+# define LZO_CC_GHS 1
+# define LZO_INFO_CC "Green Hills C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__GHS_VERSION_NUMBER)
+# if defined(_MSC_VER) && ((_MSC_VER-0) > 0)
+# define LZO_CC_GHS_MSC _MSC_VER
+# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# define LZO_CC_GHS_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
+# endif
#elif defined(__HIGHC__)
# define LZO_CC_HIGHC 1
# define LZO_INFO_CC "MetaWare High C"
# define LZO_INFO_CCVER "unknown"
+#elif defined(__HP_aCC) && ((__HP_aCC-0) > 0)
+# define LZO_CC_HPACC __HP_aCC
+# define LZO_INFO_CC "HP aCC"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__HP_aCC)
#elif defined(__IAR_SYSTEMS_ICC__)
# define LZO_CC_IARC 1
# define LZO_INFO_CC "IAR C"
@@ -552,10 +618,14 @@
# else
# define LZO_INFO_CCVER "unknown"
# endif
-#elif defined(__IBMC__)
-# define LZO_CC_IBMC 1
+#elif defined(__IBMC__) && ((__IBMC__-0) > 0)
+# define LZO_CC_IBMC __IBMC__
# define LZO_INFO_CC "IBM C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__)
+#elif defined(__IBMCPP__) && ((__IBMCPP__-0) > 0)
+# define LZO_CC_IBMC __IBMCPP__
+# define LZO_INFO_CC "IBM C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMCPP__)
#elif defined(__KEIL__) && defined(__C166__)
# define LZO_CC_KEILC 1
# define LZO_INFO_CC "Keil C"
@@ -572,16 +642,8 @@
# else
# define LZO_INFO_CCVER "unknown"
# endif
-#elif defined(_MSC_VER)
-# define LZO_CC_MSC 1
-# define LZO_INFO_CC "Microsoft C"
-# if defined(_MSC_FULL_VER)
-# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER)
-# else
-# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER)
-# endif
-#elif defined(__MWERKS__)
-# define LZO_CC_MWERKS 1
+#elif defined(__MWERKS__) && ((__MWERKS__-0) > 0)
+# define LZO_CC_MWERKS __MWERKS__
# define LZO_INFO_CC "Metrowerks C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__)
#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386)
@@ -592,6 +654,15 @@
# define LZO_CC_PACIFICC 1
# define LZO_INFO_CC "Pacific C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__)
+#elif defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__)
+# if defined(__PGIC_PATCHLEVEL__)
+# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100 + (__PGIC_PATCHLEVEL__-0))
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) "." LZO_PP_MACRO_EXPAND(__PGIC_PATCHLEVEL__)
+# else
+# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) ".0"
+# endif
+# define LZO_INFO_CC "Portland Group PGI C"
#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__))
# define LZO_CC_PGI 1
# define LZO_INFO_CC "Portland Group PGI C"
@@ -606,7 +677,7 @@
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__)
#elif defined(__SUNPRO_C)
# define LZO_INFO_CC "SunPro C"
-# if ((__SUNPRO_C)+0 > 0)
+# if ((__SUNPRO_C-0) > 0)
# define LZO_CC_SUNPROC __SUNPRO_C
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C)
# else
@@ -615,7 +686,7 @@
# endif
#elif defined(__SUNPRO_CC)
# define LZO_INFO_CC "SunPro C"
-# if ((__SUNPRO_CC)+0 > 0)
+# if ((__SUNPRO_CC-0) > 0)
# define LZO_CC_SUNPROC __SUNPRO_CC
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC)
# else
@@ -641,16 +712,46 @@
#elif defined(__ZTC__)
# define LZO_CC_ZORTECHC 1
# define LZO_INFO_CC "Zortech C"
-# if (__ZTC__ == 0x310)
+# if ((__ZTC__-0) == 0x310)
# define LZO_INFO_CCVER "0x310"
# else
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__)
# endif
+#elif defined(__GNUC__) && defined(__VERSION__)
+# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
+# elif defined(__GNUC_MINOR__)
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100)
+# else
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L)
+# endif
+# define LZO_INFO_CC "gcc"
+# define LZO_INFO_CCVER __VERSION__
+#elif defined(_MSC_VER) && ((_MSC_VER-0) > 0)
+# define LZO_CC_MSC _MSC_VER
+# define LZO_INFO_CC "Microsoft C"
+# if defined(_MSC_FULL_VER)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER)
+# else
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER)
+# endif
#else
# define LZO_CC_UNKNOWN 1
# define LZO_INFO_CC "unknown"
# define LZO_INFO_CCVER "unknown"
#endif
+#if (LZO_CC_GNUC) && defined(__OPEN64__)
+# if defined(__OPENCC__) && defined(__OPENCC_MINOR__) && defined(__OPENCC_PATCHLEVEL__)
+# define LZO_CC_OPEN64 (__OPENCC__ * 0x10000L + (__OPENCC_MINOR__-0) * 0x100 + (__OPENCC_PATCHLEVEL__-0))
+# define LZO_CC_OPEN64_GNUC LZO_CC_GNUC
+# endif
+#endif
+#if (LZO_CC_GNUC) && defined(__PCC__)
+# if defined(__PCC__) && defined(__PCC_MINOR__) && defined(__PCC_MINORMINOR__)
+# define LZO_CC_PCC (__PCC__ * 0x10000L + (__PCC_MINOR__-0) * 0x100 + (__PCC_MINORMINOR__-0))
+# define LZO_CC_PCC_GNUC LZO_CC_GNUC
+# endif
+#endif
#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER)
# error "LZO_CC_MSC: _MSC_FULL_VER is not defined"
#endif
@@ -668,8 +769,10 @@
# define LZO_INFO_ARCH "generic"
#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
# define LZO_ARCH_I086 1
-# define LZO_ARCH_IA16 1
# define LZO_INFO_ARCH "i086"
+#elif defined(__aarch64__)
+# define LZO_ARCH_ARM64 1
+# define LZO_INFO_ARCH "arm64"
#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)
# define LZO_ARCH_ALPHA 1
# define LZO_INFO_ARCH "alpha"
@@ -685,10 +788,10 @@
# define LZO_INFO_ARCH "arm_thumb"
#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__)
# define LZO_ARCH_ARM 1
-# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1)
+# if defined(__CPU_MODE__) && ((__CPU_MODE__-0) == 1)
# define LZO_ARCH_ARM_THUMB 1
# define LZO_INFO_ARCH "arm_thumb"
-# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2)
+# elif defined(__CPU_MODE__) && ((__CPU_MODE__-0) == 2)
# define LZO_INFO_ARCH "arm"
# else
# define LZO_INFO_ARCH "arm"
@@ -806,53 +909,147 @@
# error "FIXME - missing define for CPU architecture"
#endif
#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32)
-# error "FIXME - missing WIN32 define for CPU architecture"
+# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture"
#endif
#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64)
-# error "FIXME - missing WIN64 define for CPU architecture"
+# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture"
#endif
#if (LZO_OS_OS216 || LZO_OS_WIN16)
# define LZO_ARCH_I086PM 1
-# define LZO_ARCH_IA16PM 1
#elif 1 && (LZO_OS_DOS16 && defined(BLX286))
# define LZO_ARCH_I086PM 1
-# define LZO_ARCH_IA16PM 1
#elif 1 && (LZO_OS_DOS16 && defined(DOSX286))
# define LZO_ARCH_I086PM 1
-# define LZO_ARCH_IA16PM 1
#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__))
# define LZO_ARCH_I086PM 1
-# define LZO_ARCH_IA16PM 1
#endif
-#if (LZO_ARCH_ARM_THUMB) && !(LZO_ARCH_ARM)
-# error "this should not happen"
+#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64)
+# define LZO_ARCH_X64 1
+#elif (!LZO_ARCH_AMD64 && LZO_ARCH_X64) && defined(__LZO_ARCH_OVERRIDE)
+# define LZO_ARCH_AMD64 1
#endif
-#if (LZO_ARCH_I086PM) && !(LZO_ARCH_I086)
-# error "this should not happen"
+#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64)
+# define LZO_ARCH_AARCH64 1
+#elif (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) && defined(__LZO_ARCH_OVERRIDE)
+# define LZO_ARCH_ARM64 1
+#endif
+#if (LZO_ARCH_I386 && !LZO_ARCH_X86)
+# define LZO_ARCH_X86 1
+#elif (!LZO_ARCH_I386 && LZO_ARCH_X86) && defined(__LZO_ARCH_OVERRIDE)
+# define LZO_ARCH_I386 1
+#endif
+#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) || (!LZO_ARCH_AMD64 && LZO_ARCH_X64)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) || (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_I386 && !LZO_ARCH_X86) || (!LZO_ARCH_I386 && LZO_ARCH_X86)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM_THUMB && !LZO_ARCH_ARM)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM_THUMB)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM_THUMB)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM_THUMB1 && LZO_ARCH_ARM_THUMB2)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_I086PM && !LZO_ARCH_I086)
+# error "unexpected configuration - check your compiler defines"
#endif
#if (LZO_ARCH_I086)
# if (UINT_MAX != LZO_0xffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
# if (ULONG_MAX != LZO_0xffffffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
#endif
#if (LZO_ARCH_I386)
# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
# if (ULONG_MAX != LZO_0xffffffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
+# endif
+#endif
+#if (LZO_ARCH_AMD64 || LZO_ARCH_I386)
+# if !defined(LZO_TARGET_FEATURE_SSE2)
+# if defined(__SSE2__)
+# define LZO_TARGET_FEATURE_SSE2 1
+# elif defined(_MSC_VER) && ((defined(_M_IX86_FP) && ((_M_IX86_FP)+0 >= 2)) || defined(_M_AMD64))
+# define LZO_TARGET_FEATURE_SSE2 1
+# endif
+# endif
+# if !defined(LZO_TARGET_FEATURE_SSSE3)
+# if (LZO_TARGET_FEATURE_SSE2)
+# if defined(__SSSE3__)
+# define LZO_TARGET_FEATURE_SSSE3 1
+# elif defined(_MSC_VER) && defined(__AVX__)
+# define LZO_TARGET_FEATURE_SSSE3 1
+# endif
+# endif
+# endif
+# if !defined(LZO_TARGET_FEATURE_SSE4_2)
+# if (LZO_TARGET_FEATURE_SSSE3)
+# if defined(__SSE4_2__)
+# define LZO_TARGET_FEATURE_SSE4_2 1
+# endif
+# endif
+# endif
+# if !defined(LZO_TARGET_FEATURE_AVX)
+# if (LZO_TARGET_FEATURE_SSSE3)
+# if defined(__AVX__)
+# define LZO_TARGET_FEATURE_AVX 1
+# endif
+# endif
+# endif
+# if !defined(LZO_TARGET_FEATURE_AVX2)
+# if (LZO_TARGET_FEATURE_AVX)
+# if defined(__AVX2__)
+# define LZO_TARGET_FEATURE_AVX2 1
+# endif
+# endif
# endif
#endif
-#if !defined(__LZO_MM_OVERRIDE)
+#if (LZO_TARGET_FEATURE_SSSE3 && !(LZO_TARGET_FEATURE_SSE2))
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_TARGET_FEATURE_SSE4_2 && !(LZO_TARGET_FEATURE_SSSE3))
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_TARGET_FEATURE_AVX && !(LZO_TARGET_FEATURE_SSSE3))
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_TARGET_FEATURE_AVX2 && !(LZO_TARGET_FEATURE_AVX))
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM)
+# if !defined(LZO_TARGET_FEATURE_NEON)
+# if defined(__ARM_NEON__)
+# define LZO_TARGET_FEATURE_NEON 1
+# endif
+# endif
+#elif (LZO_ARCH_ARM64)
+# if !defined(LZO_TARGET_FEATURE_NEON)
+# if 1
+# define LZO_TARGET_FEATURE_NEON 1
+# endif
+# endif
+#endif
+#if 0
+#elif !defined(__LZO_MM_OVERRIDE)
#if (LZO_ARCH_I086)
#if (UINT_MAX != LZO_0xffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
#endif
#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM)
# define LZO_MM_TINY 1
@@ -879,7 +1076,7 @@
#elif (LZO_CC_ZORTECHC && defined(__VCM__))
# define LZO_MM_LARGE 1
#else
-# error "unknown memory model"
+# error "unknown LZO_ARCH_I086 memory model"
#endif
#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
#define LZO_HAVE_MM_HUGE_PTR 1
@@ -902,10 +1099,10 @@
#endif
#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR)
# if (LZO_OS_DOS16)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# elif (LZO_CC_ZORTECHC)
# else
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
#endif
#ifdef __cplusplus
@@ -937,7 +1134,7 @@ extern "C" {
#endif
#elif (LZO_ARCH_C166)
#if !defined(__MODEL__)
-# error "FIXME - C166 __MODEL__"
+# error "FIXME - LZO_ARCH_C166 __MODEL__"
#elif ((__MODEL__) == 0)
# define LZO_MM_SMALL 1
#elif ((__MODEL__) == 1)
@@ -951,11 +1148,11 @@ extern "C" {
#elif ((__MODEL__) == 5)
# define LZO_MM_XSMALL 1
#else
-# error "FIXME - C166 __MODEL__"
+# error "FIXME - LZO_ARCH_C166 __MODEL__"
#endif
#elif (LZO_ARCH_MCS251)
#if !defined(__MODEL__)
-# error "FIXME - MCS251 __MODEL__"
+# error "FIXME - LZO_ARCH_MCS251 __MODEL__"
#elif ((__MODEL__) == 0)
# define LZO_MM_SMALL 1
#elif ((__MODEL__) == 2)
@@ -967,11 +1164,11 @@ extern "C" {
#elif ((__MODEL__) == 5)
# define LZO_MM_XSMALL 1
#else
-# error "FIXME - MCS251 __MODEL__"
+# error "FIXME - LZO_ARCH_MCS251 __MODEL__"
#endif
#elif (LZO_ARCH_MCS51)
#if !defined(__MODEL__)
-# error "FIXME - MCS51 __MODEL__"
+# error "FIXME - LZO_ARCH_MCS51 __MODEL__"
#elif ((__MODEL__) == 1)
# define LZO_MM_SMALL 1
#elif ((__MODEL__) == 2)
@@ -983,7 +1180,7 @@ extern "C" {
#elif ((__MODEL__) == 5)
# define LZO_MM_XSMALL 1
#else
-# error "FIXME - MCS51 __MODEL__"
+# error "FIXME - LZO_ARCH_MCS51 __MODEL__"
#endif
#elif (LZO_ARCH_CRAY_PVP)
# define LZO_MM_PVP 1
@@ -1010,35 +1207,818 @@ extern "C" {
# error "unknown memory model"
#endif
#endif
+#if !defined(__lzo_gnuc_extension__)
+#if (LZO_CC_GNUC >= 0x020800ul)
+# define __lzo_gnuc_extension__ __extension__
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_gnuc_extension__ __extension__
+#elif (LZO_CC_IBMC >= 600)
+# define __lzo_gnuc_extension__ __extension__
+#else
+#endif
+#endif
+#if !defined(__lzo_gnuc_extension__)
+# define __lzo_gnuc_extension__ /*empty*/
+#endif
+#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) && defined(__cplusplus) && 0
+# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul))
+# define LZO_CFG_USE_NEW_STYLE_CASTS 0
+# elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1200))
+# define LZO_CFG_USE_NEW_STYLE_CASTS 0
+# else
+# define LZO_CFG_USE_NEW_STYLE_CASTS 1
+# endif
+#endif
+#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_CFG_USE_NEW_STYLE_CASTS 0
+#endif
+#if !defined(__cplusplus)
+# if defined(LZO_CFG_USE_NEW_STYLE_CASTS)
+# undef LZO_CFG_USE_NEW_STYLE_CASTS
+# endif
+# define LZO_CFG_USE_NEW_STYLE_CASTS 0
+#endif
+#if !defined(LZO_REINTERPRET_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_REINTERPRET_CAST(t,e) (reinterpret_cast<t> (e))
+# endif
+#endif
+#if !defined(LZO_REINTERPRET_CAST)
+# define LZO_REINTERPRET_CAST(t,e) ((t) (e))
+#endif
+#if !defined(LZO_STATIC_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_STATIC_CAST(t,e) (static_cast<t> (e))
+# endif
+#endif
+#if !defined(LZO_STATIC_CAST)
+# define LZO_STATIC_CAST(t,e) ((t) (e))
+#endif
+#if !defined(LZO_STATIC_CAST2)
+# define LZO_STATIC_CAST2(t1,t2,e) LZO_STATIC_CAST(t1, LZO_STATIC_CAST(t2, e))
+#endif
+#if !defined(LZO_UNCONST_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_UNCONST_CAST(t,e) (const_cast<t> (e))
+# elif (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_UNCONST_CAST(t,e) ((t) (e))
+# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((const void *) (e)))))
+# endif
+#endif
+#if !defined(LZO_UNCONST_CAST)
+# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e))))
+#endif
+#if !defined(LZO_UNCONST_VOLATILE_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_UNCONST_VOLATILE_CAST(t,e) (const_cast<t> (e))
+# elif (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) (e))
+# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((lzo_uintptr_t) ((volatile const void *) (e)))))
+# endif
+#endif
+#if !defined(LZO_UNCONST_VOLATILE_CAST)
+# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((volatile const void *) (e))))
+#endif
+#if !defined(LZO_UNVOLATILE_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_UNVOLATILE_CAST(t,e) (const_cast<t> (e))
+# elif (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_UNVOLATILE_CAST(t,e) ((t) (e))
+# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((volatile void *) (e)))))
+# endif
+#endif
+#if !defined(LZO_UNVOLATILE_CAST)
+# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((volatile void *) (e))))
+#endif
+#if !defined(LZO_UNVOLATILE_CONST_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_UNVOLATILE_CONST_CAST(t,e) (const_cast<t> (e))
+# elif (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) (e))
+# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((lzo_uintptr_t) ((volatile const void *) (e)))))
+# endif
+#endif
+#if !defined(LZO_UNVOLATILE_CONST_CAST)
+# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e))))
+#endif
+#if !defined(LZO_PCAST)
+# if (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_PCAST(t,e) ((t) (e))
+# endif
+#endif
+#if !defined(LZO_PCAST)
+# define LZO_PCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(void *, e))
+#endif
+#if !defined(LZO_CCAST)
+# if (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_CCAST(t,e) ((t) (e))
+# endif
+#endif
+#if !defined(LZO_CCAST)
+# define LZO_CCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(const void *, e))
+#endif
+#if !defined(LZO_ICONV)
+# define LZO_ICONV(t,e) LZO_STATIC_CAST(t, e)
+#endif
+#if !defined(LZO_ICAST)
+# define LZO_ICAST(t,e) LZO_STATIC_CAST(t, e)
+#endif
+#if !defined(LZO_ITRUNC)
+# define LZO_ITRUNC(t,e) LZO_STATIC_CAST(t, e)
+#endif
+#if !defined(__lzo_cte)
+# if (LZO_CC_MSC || LZO_CC_WATCOMC)
+# define __lzo_cte(e) ((void)0,(e))
+# elif 1
+# define __lzo_cte(e) ((void)0,(e))
+# endif
+#endif
+#if !defined(__lzo_cte)
+# define __lzo_cte(e) (e)
+#endif
+#if !defined(LZO_BLOCK_BEGIN)
+# define LZO_BLOCK_BEGIN do {
+# define LZO_BLOCK_END } while __lzo_cte(0)
+#endif
+#if !defined(LZO_UNUSED)
+# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
+# define LZO_UNUSED(var) ((void) &var)
+# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC)
+# define LZO_UNUSED(var) if (&var) ; else
+# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030200ul))
+# define LZO_UNUSED(var) ((void) &var)
+# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNUSED(var) ((void) var)
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_UNUSED(var) if (&var) ; else
+# elif (LZO_CC_KEILC)
+# define LZO_UNUSED(var) {LZO_EXTERN_C int lzo_unused__[1-2*!(sizeof(var)>0)];}
+# elif (LZO_CC_PACIFICC)
+# define LZO_UNUSED(var) ((void) sizeof(var))
+# elif (LZO_CC_WATCOMC) && defined(__cplusplus)
+# define LZO_UNUSED(var) ((void) var)
+# else
+# define LZO_UNUSED(var) ((void) &var)
+# endif
+#endif
+#if !defined(LZO_UNUSED_FUNC)
+# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
+# define LZO_UNUSED_FUNC(func) ((void) func)
+# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC)
+# define LZO_UNUSED_FUNC(func) if (func) ; else
+# elif (LZO_CC_CLANG || LZO_CC_LLVM)
+# define LZO_UNUSED_FUNC(func) ((void) &func)
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_UNUSED_FUNC(func) if (func) ; else
+# elif (LZO_CC_MSC)
+# define LZO_UNUSED_FUNC(func) ((void) &func)
+# elif (LZO_CC_KEILC || LZO_CC_PELLESC)
+# define LZO_UNUSED_FUNC(func) {LZO_EXTERN_C int lzo_unused_func__[1-2*!(sizeof((int)func)>0)];}
+# else
+# define LZO_UNUSED_FUNC(func) ((void) func)
+# endif
+#endif
+#if !defined(LZO_UNUSED_LABEL)
+# if (LZO_CC_CLANG >= 0x020800ul)
+# define LZO_UNUSED_LABEL(l) (__lzo_gnuc_extension__ ((void) ((const void *) &&l)))
+# elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC)
+# define LZO_UNUSED_LABEL(l) if __lzo_cte(0) goto l
+# else
+# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l
+# endif
+#endif
+#if !defined(LZO_DEFINE_UNINITIALIZED_VAR)
+# if 0
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var
+# elif 0 && (LZO_CC_GNUC)
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var
+# else
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init
+# endif
+#endif
+#if !defined(__lzo_inline)
+#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295))
+#elif defined(__cplusplus)
+# define __lzo_inline inline
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L)
+# define __lzo_inline inline
+#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550))
+# define __lzo_inline __inline
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+# define __lzo_inline __inline__
+#elif (LZO_CC_DMC)
+# define __lzo_inline __inline
+#elif (LZO_CC_GHS)
+# define __lzo_inline __inline__
+#elif (LZO_CC_IBMC >= 600)
+# define __lzo_inline __inline__
+#elif (LZO_CC_INTELC)
+# define __lzo_inline __inline
+#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405))
+# define __lzo_inline __inline
+#elif (LZO_CC_MSC && (_MSC_VER >= 900))
+# define __lzo_inline __inline
+#elif (LZO_CC_SUNPROC >= 0x5100)
+# define __lzo_inline __inline__
+#endif
+#endif
+#if defined(__lzo_inline)
+# ifndef __lzo_HAVE_inline
+# define __lzo_HAVE_inline 1
+# endif
+#else
+# define __lzo_inline /*empty*/
+#endif
+#if !defined(__lzo_forceinline)
+#if (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_IBMC >= 700)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450))
+# define __lzo_forceinline __forceinline
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800))
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
+# define __lzo_forceinline __forceinline
+#elif (LZO_CC_PGI >= 0x0d0a00ul)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_SUNPROC >= 0x5100)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#endif
+#endif
+#if defined(__lzo_forceinline)
+# ifndef __lzo_HAVE_forceinline
+# define __lzo_HAVE_forceinline 1
+# endif
+#else
+# define __lzo_forceinline __lzo_inline
+#endif
+#if !defined(__lzo_noinline)
+#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul)
+# define __lzo_noinline __attribute__((__noinline__,__used__))
+#elif (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_IBMC >= 700)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600))
+# define __lzo_noinline __declspec(noinline)
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800))
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_noinline __declspec(noinline)
+#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64))
+# if defined(__cplusplus)
+# else
+# define __lzo_noinline __declspec(noinline)
+# endif
+#elif (LZO_CC_PGI >= 0x0d0a00ul)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_SUNPROC >= 0x5100)
+# define __lzo_noinline __attribute__((__noinline__))
+#endif
+#endif
+#if defined(__lzo_noinline)
+# ifndef __lzo_HAVE_noinline
+# define __lzo_HAVE_noinline 1
+# endif
+#else
+# define __lzo_noinline /*empty*/
+#endif
+#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if !defined(__lzo_static_inline)
+#if (LZO_CC_IBMC)
+# define __lzo_static_inline __lzo_gnuc_extension__ static __lzo_inline
+#endif
+#endif
+#if !defined(__lzo_static_inline)
+# define __lzo_static_inline static __lzo_inline
+#endif
+#if !defined(__lzo_static_forceinline)
+#if (LZO_CC_IBMC)
+# define __lzo_static_forceinline __lzo_gnuc_extension__ static __lzo_forceinline
+#endif
+#endif
+#if !defined(__lzo_static_forceinline)
+# define __lzo_static_forceinline static __lzo_forceinline
+#endif
+#if !defined(__lzo_static_noinline)
+#if (LZO_CC_IBMC)
+# define __lzo_static_noinline __lzo_gnuc_extension__ static __lzo_noinline
+#endif
+#endif
+#if !defined(__lzo_static_noinline)
+# define __lzo_static_noinline static __lzo_noinline
+#endif
+#if !defined(__lzo_c99_extern_inline)
+#if defined(__GNUC_GNU_INLINE__)
+# define __lzo_c99_extern_inline __lzo_inline
+#elif defined(__GNUC_STDC_INLINE__)
+# define __lzo_c99_extern_inline extern __lzo_inline
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L)
+# define __lzo_c99_extern_inline extern __lzo_inline
+#endif
+#if !defined(__lzo_c99_extern_inline) && (__lzo_HAVE_inline)
+# define __lzo_c99_extern_inline __lzo_inline
+#endif
+#endif
+#if defined(__lzo_c99_extern_inline)
+# ifndef __lzo_HAVE_c99_extern_inline
+# define __lzo_HAVE_c99_extern_inline 1
+# endif
+#else
+# define __lzo_c99_extern_inline /*empty*/
+#endif
+#if !defined(__lzo_may_alias)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_may_alias __attribute__((__may_alias__))
+#elif (LZO_CC_CLANG >= 0x020900ul)
+# define __lzo_may_alias __attribute__((__may_alias__))
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1210)) && 0
+# define __lzo_may_alias __attribute__((__may_alias__))
+#elif (LZO_CC_PGI >= 0x0d0a00ul) && 0
+# define __lzo_may_alias __attribute__((__may_alias__))
+#endif
+#endif
+#if defined(__lzo_may_alias)
+# ifndef __lzo_HAVE_may_alias
+# define __lzo_HAVE_may_alias 1
+# endif
+#else
+# define __lzo_may_alias /*empty*/
+#endif
+#if !defined(__lzo_noreturn)
+#if (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_IBMC >= 700)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450))
+# define __lzo_noreturn __declspec(noreturn)
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600))
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
+# define __lzo_noreturn __declspec(noreturn)
+#elif (LZO_CC_PGI >= 0x0d0a00ul)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#endif
+#endif
+#if defined(__lzo_noreturn)
+# ifndef __lzo_HAVE_noreturn
+# define __lzo_HAVE_noreturn 1
+# endif
+#else
+# define __lzo_noreturn /*empty*/
+#endif
+#if !defined(__lzo_nothrow)
+#if (LZO_CC_GNUC >= 0x030300ul)
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) && defined(__cplusplus)
+# define __lzo_nothrow __declspec(nothrow)
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 900))
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus)
+# define __lzo_nothrow __declspec(nothrow)
+#endif
+#endif
+#if defined(__lzo_nothrow)
+# ifndef __lzo_HAVE_nothrow
+# define __lzo_HAVE_nothrow 1
+# endif
+#else
+# define __lzo_nothrow /*empty*/
+#endif
+#if !defined(__lzo_restrict)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_IBMC >= 800) && !defined(__cplusplus)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_IBMC >= 1210)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600))
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600))
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_MSC && (_MSC_VER >= 1400))
+# define __lzo_restrict __restrict
+#elif (LZO_CC_PGI >= 0x0d0a00ul)
+# define __lzo_restrict __restrict__
+#endif
+#endif
+#if defined(__lzo_restrict)
+# ifndef __lzo_HAVE_restrict
+# define __lzo_HAVE_restrict 1
+# endif
+#else
+# define __lzo_restrict /*empty*/
+#endif
+#if !defined(__lzo_alignof)
+#if (LZO_CC_ARMCC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+# define __lzo_alignof(e) __alignof__(e)
+#elif (LZO_CC_GHS) && !defined(__cplusplus)
+# define __lzo_alignof(e) __alignof__(e)
+#elif (LZO_CC_IBMC >= 600)
+# define __lzo_alignof(e) (__lzo_gnuc_extension__ __alignof__(e))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700))
+# define __lzo_alignof(e) __alignof__(e)
+#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_alignof(e) __alignof(e)
+#elif (LZO_CC_SUNPROC >= 0x5100)
+# define __lzo_alignof(e) __alignof__(e)
+#endif
+#endif
+#if defined(__lzo_alignof)
+# ifndef __lzo_HAVE_alignof
+# define __lzo_HAVE_alignof 1
+# endif
+#endif
+#if !defined(__lzo_struct_packed)
+#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus)
+#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul))
+#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus)
+#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul))
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus)
+#elif (LZO_CC_GNUC >= 0x030400ul) && !(LZO_CC_PCC_GNUC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386)
+# define __lzo_struct_packed(s) struct s {
+# define __lzo_struct_packed_end() } __attribute__((__gcc_struct__,__packed__));
+# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__gcc_struct__,__packed__));
+#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_struct_packed(s) struct s {
+# define __lzo_struct_packed_end() } __attribute__((__packed__));
+# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__));
+#elif (LZO_CC_IBMC >= 700)
+# define __lzo_struct_packed(s) __lzo_gnuc_extension__ struct s {
+# define __lzo_struct_packed_end() } __attribute__((__packed__));
+# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__));
+#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_struct_packed(s) __pragma(pack(push,1)) struct s {
+# define __lzo_struct_packed_end() } __pragma(pack(pop));
+#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900))
+# define __lzo_struct_packed(s) _Packed struct s {
+# define __lzo_struct_packed_end() };
+#endif
+#endif
+#if defined(__lzo_struct_packed) && !defined(__lzo_struct_packed_ma)
+# define __lzo_struct_packed_ma(s) __lzo_struct_packed(s)
+#endif
+#if defined(__lzo_struct_packed_end) && !defined(__lzo_struct_packed_ma_end)
+# define __lzo_struct_packed_ma_end() __lzo_struct_packed_end()
+#endif
+#if !defined(__lzo_byte_struct)
+#if defined(__lzo_struct_packed)
+# define __lzo_byte_struct(s,n) __lzo_struct_packed(s) unsigned char a[n]; __lzo_struct_packed_end()
+# define __lzo_byte_struct_ma(s,n) __lzo_struct_packed_ma(s) unsigned char a[n]; __lzo_struct_packed_ma_end()
+#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_PGI || (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_byte_struct(s,n) struct s { unsigned char a[n]; } __attribute__((__packed__));
+# define __lzo_byte_struct_ma(s,n) struct s { unsigned char a[n]; } __lzo_may_alias __attribute__((__packed__));
+#endif
+#endif
+#if defined(__lzo_byte_struct) && !defined(__lzo_byte_struct_ma)
+# define __lzo_byte_struct_ma(s,n) __lzo_byte_struct(s,n)
+#endif
+#if !defined(__lzo_struct_align16) && (__lzo_HAVE_alignof)
+#if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul))
+#elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus)
+#elif (LZO_CC_CILLY || LZO_CC_PCC)
+#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_struct_align16(s) struct __declspec(align(16)) s {
+# define __lzo_struct_align16_end() };
+# define __lzo_struct_align32(s) struct __declspec(align(32)) s {
+# define __lzo_struct_align32_end() };
+# define __lzo_struct_align64(s) struct __declspec(align(64)) s {
+# define __lzo_struct_align64_end() };
+#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || (LZO_CC_IBMC >= 700) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_struct_align16(s) struct s {
+# define __lzo_struct_align16_end() } __attribute__((__aligned__(16)));
+# define __lzo_struct_align32(s) struct s {
+# define __lzo_struct_align32_end() } __attribute__((__aligned__(32)));
+# define __lzo_struct_align64(s) struct s {
+# define __lzo_struct_align64_end() } __attribute__((__aligned__(64)));
+#endif
+#endif
+#if !defined(__lzo_union_um)
+#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus)
+#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul))
+#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus)
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER < 810))
+#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul))
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus)
+#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_union_am(s) union s {
+# define __lzo_union_am_end() } __lzo_may_alias;
+# define __lzo_union_um(s) union s {
+# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__));
+#elif (LZO_CC_IBMC >= 700)
+# define __lzo_union_am(s) __lzo_gnuc_extension__ union s {
+# define __lzo_union_am_end() } __lzo_may_alias;
+# define __lzo_union_um(s) __lzo_gnuc_extension__ union s {
+# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__));
+#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_union_um(s) __pragma(pack(push,1)) union s {
+# define __lzo_union_um_end() } __pragma(pack(pop));
+#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900))
+# define __lzo_union_um(s) _Packed union s {
+# define __lzo_union_um_end() };
+#endif
+#endif
+#if !defined(__lzo_union_am)
+# define __lzo_union_am(s) union s {
+# define __lzo_union_am_end() };
+#endif
+#if !defined(__lzo_constructor)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_constructor __attribute__((__constructor__,__used__))
+#elif (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_constructor __attribute__((__constructor__))
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800))
+# define __lzo_constructor __attribute__((__constructor__,__used__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_constructor __attribute__((__constructor__))
+#endif
+#endif
+#if defined(__lzo_constructor)
+# ifndef __lzo_HAVE_constructor
+# define __lzo_HAVE_constructor 1
+# endif
+#endif
+#if !defined(__lzo_destructor)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_destructor __attribute__((__destructor__,__used__))
+#elif (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_destructor __attribute__((__destructor__))
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800))
+# define __lzo_destructor __attribute__((__destructor__,__used__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_destructor __attribute__((__destructor__))
+#endif
+#endif
+#if defined(__lzo_destructor)
+# ifndef __lzo_HAVE_destructor
+# define __lzo_HAVE_destructor 1
+# endif
+#endif
+#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if !defined(__lzo_likely) && !defined(__lzo_unlikely)
+#if (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#elif (LZO_CC_IBMC >= 1010)
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800))
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#endif
+#endif
+#if defined(__lzo_likely)
+# ifndef __lzo_HAVE_likely
+# define __lzo_HAVE_likely 1
+# endif
+#else
+# define __lzo_likely(e) (e)
+#endif
+#if defined(__lzo_unlikely)
+# ifndef __lzo_HAVE_unlikely
+# define __lzo_HAVE_unlikely 1
+# endif
+#else
+# define __lzo_unlikely(e) (e)
+#endif
+#if !defined(__lzo_static_unused_void_func)
+# if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+# define __lzo_static_unused_void_func(f) static void __attribute__((__unused__)) f(void)
+# else
+# define __lzo_static_unused_void_func(f) static __lzo_inline void f(void)
+# endif
+#endif
+#if !defined(__lzo_loop_forever)
+# if (LZO_CC_IBMC)
+# define __lzo_loop_forever() LZO_BLOCK_BEGIN for (;;) { ; } LZO_BLOCK_END
+# else
+# define __lzo_loop_forever() do { ; } while __lzo_cte(1)
+# endif
+#endif
+#if !defined(__lzo_unreachable)
+#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x020800ul))
+# define __lzo_unreachable() __builtin_unreachable();
+#elif (LZO_CC_GNUC >= 0x040500ul)
+# define __lzo_unreachable() __builtin_unreachable();
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1300)) && 1
+# define __lzo_unreachable() __builtin_unreachable();
+#endif
+#endif
+#if defined(__lzo_unreachable)
+# ifndef __lzo_HAVE_unreachable
+# define __lzo_HAVE_unreachable 1
+# endif
+#else
+# if 0
+# define __lzo_unreachable() ((void)0);
+# else
+# define __lzo_unreachable() __lzo_loop_forever();
+# endif
+#endif
+#ifndef __LZO_CTA_NAME
+#if (LZO_CFG_USE_COUNTER)
+# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__COUNTER__)
+#else
+# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__LINE__)
+#endif
+#endif
+#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER)
+# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END
+# elif (LZO_CC_DMC || LZO_CC_SYMANTECC)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1u-2*!(e)]; LZO_EXTERN_C_END
+# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END
+# elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020900ul)) && defined(__cplusplus)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN int __LZO_CTA_NAME(lzo_cta_f__)(int [1-2*!(e)]); LZO_EXTERN_C_END
+# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__)); LZO_EXTERN_C_END
+# else
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-2*!(e)]; LZO_EXTERN_C_END
+# endif
+#endif
+#if !defined(LZO_COMPILE_TIME_ASSERT)
+# if (LZO_CC_AZTECC)
+# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-!(e)];}
+# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
+# define LZO_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));}
+# elif (LZO_CC_GNUC >= 0x040700ul) && (LZO_CFG_USE_COUNTER) && defined(__cplusplus)
+# define LZO_COMPILE_TIME_ASSERT(e) {enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__));}
+# elif (LZO_CC_GNUC >= 0x040700ul)
+# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));}
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# else
+# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)];}
+# endif
+#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(1 == 1)
+#if defined(__cplusplus)
+extern "C" { LZO_COMPILE_TIME_ASSERT_HEADER(2 == 2) }
+#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(3 == 3)
+#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64)
+# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC)
+# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
+# define __lzo_cdecl __cdecl
+# define __lzo_cdecl_atexit /*empty*/
+# define __lzo_cdecl_main __cdecl
+# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
+# define __lzo_cdecl_qsort __pascal
+# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
+# define __lzo_cdecl_qsort _stdcall
+# else
+# define __lzo_cdecl_qsort __cdecl
+# endif
+# elif (LZO_CC_WATCOMC)
+# define __lzo_cdecl __cdecl
+# else
+# define __lzo_cdecl __cdecl
+# define __lzo_cdecl_atexit __cdecl
+# define __lzo_cdecl_main __cdecl
+# define __lzo_cdecl_qsort __cdecl
+# endif
+# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC)
+# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
+# define __lzo_cdecl_sighandler __pascal
+# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
+# define __lzo_cdecl_sighandler _stdcall
+# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE)
+# define __lzo_cdecl_sighandler __clrcall
+# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700))
+# if defined(_DLL)
+# define __lzo_cdecl_sighandler _far _cdecl _loadds
+# elif defined(_MT)
+# define __lzo_cdecl_sighandler _far _cdecl
+# else
+# define __lzo_cdecl_sighandler _cdecl
+# endif
+# else
+# define __lzo_cdecl_sighandler __cdecl
+# endif
+#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC)
+# define __lzo_cdecl __cdecl
+#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC))
+# define __lzo_cdecl cdecl
+#endif
+#if !defined(__lzo_cdecl)
+# define __lzo_cdecl /*empty*/
+#endif
+#if !defined(__lzo_cdecl_atexit)
+# define __lzo_cdecl_atexit /*empty*/
+#endif
+#if !defined(__lzo_cdecl_main)
+# define __lzo_cdecl_main /*empty*/
+#endif
+#if !defined(__lzo_cdecl_qsort)
+# define __lzo_cdecl_qsort /*empty*/
+#endif
+#if !defined(__lzo_cdecl_sighandler)
+# define __lzo_cdecl_sighandler /*empty*/
+#endif
+#if !defined(__lzo_cdecl_va)
+# define __lzo_cdecl_va __lzo_cdecl
+#endif
+#if !(LZO_CFG_NO_WINDOWS_H)
+#if !defined(LZO_HAVE_WINDOWS_H)
+#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64)
+# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000))
+# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__)
+# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul)))
+# else
+# define LZO_HAVE_WINDOWS_H 1
+# endif
+#endif
+#endif
+#endif
+#ifndef LZO_SIZEOF_SHORT
#if defined(SIZEOF_SHORT)
# define LZO_SIZEOF_SHORT (SIZEOF_SHORT)
+#elif defined(__SIZEOF_SHORT__)
+# define LZO_SIZEOF_SHORT (__SIZEOF_SHORT__)
+#endif
#endif
+#ifndef LZO_SIZEOF_INT
#if defined(SIZEOF_INT)
# define LZO_SIZEOF_INT (SIZEOF_INT)
+#elif defined(__SIZEOF_INT__)
+# define LZO_SIZEOF_INT (__SIZEOF_INT__)
#endif
+#endif
+#ifndef LZO_SIZEOF_LONG
#if defined(SIZEOF_LONG)
# define LZO_SIZEOF_LONG (SIZEOF_LONG)
+#elif defined(__SIZEOF_LONG__)
+# define LZO_SIZEOF_LONG (__SIZEOF_LONG__)
+#endif
#endif
+#ifndef LZO_SIZEOF_LONG_LONG
#if defined(SIZEOF_LONG_LONG)
# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG)
+#elif defined(__SIZEOF_LONG_LONG__)
+# define LZO_SIZEOF_LONG_LONG (__SIZEOF_LONG_LONG__)
#endif
+#endif
+#ifndef LZO_SIZEOF___INT16
#if defined(SIZEOF___INT16)
# define LZO_SIZEOF___INT16 (SIZEOF___INT16)
#endif
+#endif
+#ifndef LZO_SIZEOF___INT32
#if defined(SIZEOF___INT32)
# define LZO_SIZEOF___INT32 (SIZEOF___INT32)
#endif
+#endif
+#ifndef LZO_SIZEOF___INT64
#if defined(SIZEOF___INT64)
# define LZO_SIZEOF___INT64 (SIZEOF___INT64)
#endif
+#endif
+#ifndef LZO_SIZEOF_VOID_P
#if defined(SIZEOF_VOID_P)
# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P)
+#elif defined(__SIZEOF_POINTER__)
+# define LZO_SIZEOF_VOID_P (__SIZEOF_POINTER__)
#endif
+#endif
+#ifndef LZO_SIZEOF_SIZE_T
#if defined(SIZEOF_SIZE_T)
# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T)
+#elif defined(__SIZEOF_SIZE_T__)
+# define LZO_SIZEOF_SIZE_T (__SIZEOF_SIZE_T__)
+#endif
#endif
+#ifndef LZO_SIZEOF_PTRDIFF_T
#if defined(SIZEOF_PTRDIFF_T)
# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T)
+#elif defined(__SIZEOF_PTRDIFF_T__)
+# define LZO_SIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__)
+#endif
#endif
#define __LZO_LSR(x,b) (((x)+0ul) >> (b))
#if !defined(LZO_SIZEOF_SHORT)
@@ -1060,6 +2040,7 @@ extern "C" {
# error "LZO_SIZEOF_SHORT"
# endif
#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SHORT == sizeof(short))
#if !defined(LZO_SIZEOF_INT)
# if (LZO_ARCH_CRAY_PVP)
# define LZO_SIZEOF_INT 8
@@ -1081,6 +2062,7 @@ extern "C" {
# error "LZO_SIZEOF_INT"
# endif
#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_INT == sizeof(int))
#if !defined(LZO_SIZEOF_LONG)
# if (ULONG_MAX == LZO_0xffffffffL)
# define LZO_SIZEOF_LONG 4
@@ -1090,6 +2072,8 @@ extern "C" {
# define LZO_SIZEOF_LONG 2
# elif (__LZO_LSR(ULONG_MAX,31) == 1)
# define LZO_SIZEOF_LONG 4
+# elif (__LZO_LSR(ULONG_MAX,39) == 1)
+# define LZO_SIZEOF_LONG 5
# elif (__LZO_LSR(ULONG_MAX,63) == 1)
# define LZO_SIZEOF_LONG 8
# elif (__LZO_LSR(ULONG_MAX,127) == 1)
@@ -1098,11 +2082,12 @@ extern "C" {
# error "LZO_SIZEOF_LONG"
# endif
#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_LONG == sizeof(long))
#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64)
#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8)
# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__)
# if (LZO_CC_GNUC >= 0x030300ul)
-# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0)
+# if ((__LONG_MAX__-0) == (__LONG_LONG_MAX__-0))
# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG
# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1)
# define LZO_SIZEOF_LONG_LONG 4
@@ -1116,7 +2101,7 @@ extern "C" {
#if (LZO_ARCH_I086 && LZO_CC_DMC)
#elif (LZO_CC_CILLY) && defined(__GNUC__)
# define LZO_SIZEOF_LONG_LONG 8
-#elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define LZO_SIZEOF_LONG_LONG 8
#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400))
# define LZO_SIZEOF_LONG_LONG 8
@@ -1138,11 +2123,13 @@ extern "C" {
# define LZO_SIZEOF___INT64 8
#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100)))
# define LZO_SIZEOF___INT64 8
-#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64))
+#elif (LZO_CC_GHS && defined(__LLONG_BIT) && ((__LLONG_BIT-0) == 64))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && ((_INTEGRAL_MAX_BITS-0) == 64))
# define LZO_SIZEOF___INT64 8
#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__)
# define LZO_SIZEOF_LONG_LONG 8
-#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64)
+#elif (defined(__vms) || defined(__VMS)) && ((__INITIAL_POINTER_SIZE-0) == 64)
# define LZO_SIZEOF_LONG_LONG 8
#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2)
#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
@@ -1155,87 +2142,127 @@ extern "C" {
# undef LZO_SIZEOF_LONG_LONG
# endif
#endif
-#if (LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG)
+#if (LZO_CFG_NO_LONG_LONG)
+# undef LZO_SIZEOF_LONG_LONG
+#elif defined(__NO_LONG_LONG)
+# undef LZO_SIZEOF_LONG_LONG
+#elif defined(_NO_LONGLONG)
# undef LZO_SIZEOF_LONG_LONG
#endif
-#if !defined(LZO_SIZEOF_VOID_P)
-#if (LZO_ARCH_I086)
-# define __LZO_WORDSIZE 2
-# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM)
-# define LZO_SIZEOF_VOID_P 2
-# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE)
-# define LZO_SIZEOF_VOID_P 4
+#if !defined(LZO_WORDSIZE)
+#if (LZO_ARCH_ALPHA)
+# define LZO_WORDSIZE 8
+#elif (LZO_ARCH_AMD64)
+# define LZO_WORDSIZE 8
+#elif (LZO_ARCH_AVR)
+# define LZO_WORDSIZE 1
+#elif (LZO_ARCH_H8300)
+# if defined(__NORMAL_MODE__)
+# define LZO_WORDSIZE 4
+# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__)
+# define LZO_WORDSIZE 4
# else
-# error "LZO_MM"
+# define LZO_WORDSIZE 2
# endif
-#elif (LZO_ARCH_AVR || LZO_ARCH_Z80)
-# define __LZO_WORDSIZE 1
+#elif (LZO_ARCH_I086)
+# define LZO_WORDSIZE 2
+#elif (LZO_ARCH_IA64)
+# define LZO_WORDSIZE 8
+#elif (LZO_ARCH_M16C)
+# define LZO_WORDSIZE 2
+#elif (LZO_ARCH_SPU)
+# define LZO_WORDSIZE 4
+#elif (LZO_ARCH_Z80)
+# define LZO_WORDSIZE 1
+#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__))
+# define LZO_WORDSIZE 8
+#elif (LZO_OS_OS400 || defined(__OS400__))
+# define LZO_WORDSIZE 8
+#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64)
+# define LZO_WORDSIZE 8
+#endif
+#endif
+#if !defined(LZO_SIZEOF_VOID_P)
+#if defined(__ILP32__) || defined(__ILP32) || defined(_ILP32)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
+# define LZO_SIZEOF_VOID_P 4
+#elif defined(__ILP64__) || defined(__ILP64) || defined(_ILP64)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 8)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8)
+# define LZO_SIZEOF_VOID_P 8
+#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
+# define LZO_SIZEOF_VOID_P 8
+#elif defined(__LP64__) || defined(__LP64) || defined(_LP64)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8)
+# define LZO_SIZEOF_VOID_P 8
+#elif (LZO_ARCH_AVR)
# define LZO_SIZEOF_VOID_P 2
#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430)
# define LZO_SIZEOF_VOID_P 2
#elif (LZO_ARCH_H8300)
# if defined(__NORMAL_MODE__)
-# define __LZO_WORDSIZE 4
# define LZO_SIZEOF_VOID_P 2
# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__)
-# define __LZO_WORDSIZE 4
# define LZO_SIZEOF_VOID_P 4
# else
-# define __LZO_WORDSIZE 2
# define LZO_SIZEOF_VOID_P 2
# endif
# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4)
# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT
# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT
# endif
+#elif (LZO_ARCH_I086)
+# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM)
+# define LZO_SIZEOF_VOID_P 2
+# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE)
+# define LZO_SIZEOF_VOID_P 4
+# else
+# error "invalid LZO_ARCH_I086 memory model"
+# endif
#elif (LZO_ARCH_M16C)
-# define __LZO_WORDSIZE 2
# if defined(__m32c_cpu__) || defined(__m32cm_cpu__)
# define LZO_SIZEOF_VOID_P 4
# else
# define LZO_SIZEOF_VOID_P 2
# endif
+#elif (LZO_ARCH_SPU)
+# define LZO_SIZEOF_VOID_P 4
+#elif (LZO_ARCH_Z80)
+# define LZO_SIZEOF_VOID_P 2
#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__))
-# define __LZO_WORDSIZE 8
# define LZO_SIZEOF_VOID_P 4
-#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64)
-# define __LZO_WORDSIZE 8
-# define LZO_SIZEOF_VOID_P 8
-#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__)
-# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG
-# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
-# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
#elif (LZO_OS_OS400 || defined(__OS400__))
-# define __LZO_WORDSIZE LZO_SIZEOF_LONG
-# define LZO_SIZEOF_VOID_P 16
-# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
-# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+# if defined(__LLP64_IFC__)
+# define LZO_SIZEOF_VOID_P 8
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+# else
+# define LZO_SIZEOF_VOID_P 16
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+# endif
#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64)
# define LZO_SIZEOF_VOID_P 8
# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
-#elif (LZO_ARCH_SPU)
-# if 0
-# define __LZO_WORDSIZE 16
-# endif
-# define LZO_SIZEOF_VOID_P 4
-#else
-# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG
#endif
#endif
-#if !defined(LZO_WORDSIZE)
-# if defined(__LZO_WORDSIZE)
-# define LZO_WORDSIZE __LZO_WORDSIZE
-# else
-# define LZO_WORDSIZE LZO_SIZEOF_VOID_P
-# endif
+#if !defined(LZO_SIZEOF_VOID_P)
+# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG
#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_VOID_P == sizeof(void *))
#if !defined(LZO_SIZEOF_SIZE_T)
#if (LZO_ARCH_I086 || LZO_ARCH_M16C)
# define LZO_SIZEOF_SIZE_T 2
-#else
+#endif
+#endif
+#if !defined(LZO_SIZEOF_SIZE_T)
# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P
#endif
+#if defined(offsetof)
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SIZE_T == sizeof(size_t))
#endif
#if !defined(LZO_SIZEOF_PTRDIFF_T)
#if (LZO_ARCH_I086)
@@ -1248,11 +2275,18 @@ extern "C" {
# define LZO_SIZEOF_PTRDIFF_T 2
# endif
# else
-# error "LZO_MM"
+# error "invalid LZO_ARCH_I086 memory model"
# endif
-#else
+#endif
+#endif
+#if !defined(LZO_SIZEOF_PTRDIFF_T)
# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T
#endif
+#if defined(offsetof)
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t))
+#endif
+#if !defined(LZO_WORDSIZE)
+# define LZO_WORDSIZE LZO_SIZEOF_VOID_P
#endif
#if (LZO_ABI_NEUTRAL_ENDIAN)
# undef LZO_ABI_BIG_ENDIAN
@@ -1264,7 +2298,7 @@ extern "C" {
# define LZO_ABI_LITTLE_ENDIAN 1
#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430)
# define LZO_ABI_LITTLE_ENDIAN 1
-#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390)
+#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390 || LZO_ARCH_SPU)
# define LZO_ABI_BIG_ENDIAN 1
#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__)
# if (__LITTLE_ENDIAN__ == 1)
@@ -1280,6 +2314,19 @@ extern "C" {
# define LZO_ABI_BIG_ENDIAN 1
#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__)
# define LZO_ABI_LITTLE_ENDIAN 1
+#elif 1 && (LZO_ARCH_ARM && LZO_CC_ARMCC_ARMCC)
+# if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
+# error "unexpected configuration - check your compiler defines"
+# elif defined(__BIG_ENDIAN)
+# define LZO_ABI_BIG_ENDIAN 1
+# else
+# define LZO_ABI_LITTLE_ENDIAN 1
+# endif
+# define LZO_ABI_LITTLE_ENDIAN 1
+#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EB__) && !defined(__AARCH64EL__)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EL__) && !defined(__AARCH64EB__)
+# define LZO_ABI_LITTLE_ENDIAN 1
#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__)
# define LZO_ABI_BIG_ENDIAN 1
#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__)
@@ -1287,7 +2334,7 @@ extern "C" {
#endif
#endif
#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
#endif
#if (LZO_ABI_BIG_ENDIAN)
# define LZO_INFO_ABI_ENDIAN "be"
@@ -1302,6 +2349,9 @@ extern "C" {
#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2)
# define LZO_ABI_ILP16 1
# define LZO_INFO_ABI_PM "ilp16"
+#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4)
+# define LZO_ABI_LP32 1
+# define LZO_INFO_ABI_PM "lp32"
#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4)
# define LZO_ABI_ILP32 1
# define LZO_INFO_ABI_PM "ilp32"
@@ -1318,7 +2368,8 @@ extern "C" {
# define LZO_ABI_IP32L64 1
# define LZO_INFO_ABI_PM "ip32l64"
#endif
-#if !defined(__LZO_LIBC_OVERRIDE)
+#if 0
+#elif !defined(__LZO_LIBC_OVERRIDE)
#if (LZO_LIBC_NAKED)
# define LZO_INFO_LIBC "naked"
#elif (LZO_LIBC_FREESTANDING)
@@ -1329,6 +2380,9 @@ extern "C" {
# define LZO_INFO_LIBC "isoc90"
#elif (LZO_LIBC_ISOC99)
# define LZO_INFO_LIBC "isoc99"
+#elif (LZO_CC_ARMCC_ARMCC) && defined(__ARMCLIB_VERSION)
+# define LZO_LIBC_ISOC90 1
+# define LZO_INFO_LIBC "isoc90"
#elif defined(__dietlibc__)
# define LZO_LIBC_DIETLIBC 1
# define LZO_INFO_LIBC "dietlibc"
@@ -1337,13 +2391,13 @@ extern "C" {
# define LZO_INFO_LIBC "newlib"
#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__)
# if defined(__UCLIBC_SUBLEVEL__)
-# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__)
+# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + (__UCLIBC_MINOR__-0) * 0x100 + (__UCLIBC_SUBLEVEL__-0))
# else
# define LZO_LIBC_UCLIBC 0x00090bL
# endif
-# define LZO_INFO_LIBC "uclibc"
+# define LZO_INFO_LIBC "uc" "libc"
#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__)
-# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100)
+# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + (__GLIBC_MINOR__-0) * 0x100)
# define LZO_INFO_LIBC "glibc"
#elif (LZO_CC_MWERKS) && defined(__MSL__)
# define LZO_LIBC_MSL __MSL__
@@ -1356,424 +2410,160 @@ extern "C" {
# define LZO_INFO_LIBC "default"
#endif
#endif
-#if !defined(__lzo_gnuc_extension__)
-#if (LZO_CC_GNUC >= 0x020800ul)
-# define __lzo_gnuc_extension__ __extension__
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_gnuc_extension__ __extension__
-#else
-# define __lzo_gnuc_extension__ /*empty*/
-#endif
-#endif
-#if !defined(__lzo_ua_volatile)
-# define __lzo_ua_volatile volatile
-#endif
-#if !defined(__lzo_alignof)
-#if (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
-# define __lzo_alignof(e) __alignof__(e)
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700))
-# define __lzo_alignof(e) __alignof__(e)
-#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
-# define __lzo_alignof(e) __alignof(e)
-#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
-# define __lzo_alignof(e) __alignof__(e)
-#endif
-#endif
-#if defined(__lzo_alignof)
-# define __lzo_HAVE_alignof 1
-#endif
-#if !defined(__lzo_constructor)
-#if (LZO_CC_GNUC >= 0x030400ul)
-# define __lzo_constructor __attribute__((__constructor__,__used__))
-#elif (LZO_CC_GNUC >= 0x020700ul)
-# define __lzo_constructor __attribute__((__constructor__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_constructor __attribute__((__constructor__))
-#endif
-#endif
-#if defined(__lzo_constructor)
-# define __lzo_HAVE_constructor 1
-#endif
-#if !defined(__lzo_destructor)
-#if (LZO_CC_GNUC >= 0x030400ul)
-# define __lzo_destructor __attribute__((__destructor__,__used__))
-#elif (LZO_CC_GNUC >= 0x020700ul)
-# define __lzo_destructor __attribute__((__destructor__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_destructor __attribute__((__destructor__))
-#endif
-#endif
-#if defined(__lzo_destructor)
-# define __lzo_HAVE_destructor 1
-#endif
-#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor)
-# error "this should not happen"
-#endif
-#if !defined(__lzo_inline)
-#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295))
-#elif defined(__cplusplus)
-# define __lzo_inline inline
-#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550))
-# define __lzo_inline __inline
-#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
-# define __lzo_inline __inline__
-#elif (LZO_CC_DMC)
-# define __lzo_inline __inline
-#elif (LZO_CC_INTELC)
-# define __lzo_inline __inline
-#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405))
-# define __lzo_inline __inline
-#elif (LZO_CC_MSC && (_MSC_VER >= 900))
-# define __lzo_inline __inline
-#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
-# define __lzo_inline __inline__
-#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
-# define __lzo_inline inline
-#endif
+#if (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
+# define LZO_ASM_SYNTAX_MSC 1
+#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
+#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul))
+#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+# define LZO_ASM_SYNTAX_GNUC 1
+#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+# define LZO_ASM_SYNTAX_GNUC 1
+#elif (LZO_CC_GNUC)
+# define LZO_ASM_SYNTAX_GNUC 1
#endif
-#if defined(__lzo_inline)
-# define __lzo_HAVE_inline 1
+#if (LZO_ASM_SYNTAX_GNUC)
+#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul))
+# define __LZO_ASM_CLOBBER "ax"
+# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/
+# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY /*empty*/
+# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1000))
+# define __LZO_ASM_CLOBBER "memory"
+# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/
+# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "memory"
+# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/
#else
-# define __lzo_inline /*empty*/
-#endif
-#if !defined(__lzo_forceinline)
-#if (LZO_CC_GNUC >= 0x030200ul)
-# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC)
-# define __lzo_forceinline __forceinline
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
-# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
-#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
-# define __lzo_forceinline __forceinline
-#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
-# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+# define __LZO_ASM_CLOBBER "cc", "memory"
+# define __LZO_ASM_CLOBBER_LIST_CC : "cc"
+# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "cc", "memory"
+# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/
#endif
#endif
-#if defined(__lzo_forceinline)
-# define __lzo_HAVE_forceinline 1
-#else
-# define __lzo_forceinline /*empty*/
-#endif
-#if !defined(__lzo_noinline)
-#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul)
-# define __lzo_noinline __attribute__((__noinline__,__used__))
-#elif (LZO_CC_GNUC >= 0x030200ul)
-# define __lzo_noinline __attribute__((__noinline__))
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC)
-# define __lzo_noinline __declspec(noinline)
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
-# define __lzo_noinline __attribute__((__noinline__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_noinline __attribute__((__noinline__))
-#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
-# define __lzo_noinline __declspec(noinline)
-#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64))
-# if defined(__cplusplus)
-# else
-# define __lzo_noinline __declspec(noinline)
+#if (LZO_ARCH_ALPHA)
+# define LZO_OPT_AVOID_UINT_INDEX 1
+#elif (LZO_ARCH_AMD64)
+# define LZO_OPT_AVOID_INT_INDEX 1
+# define LZO_OPT_AVOID_UINT_INDEX 1
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
# endif
-#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
-# define __lzo_noinline __attribute__((__noinline__))
-#endif
-#endif
-#if defined(__lzo_noinline)
-# define __lzo_HAVE_noinline 1
-#else
-# define __lzo_noinline /*empty*/
-#endif
-#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline)
-# error "this should not happen"
-#endif
-#if !defined(__lzo_noreturn)
-#if (LZO_CC_GNUC >= 0x020700ul)
-# define __lzo_noreturn __attribute__((__noreturn__))
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC)
-# define __lzo_noreturn __declspec(noreturn)
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
-# define __lzo_noreturn __attribute__((__noreturn__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_noreturn __attribute__((__noreturn__))
-#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
-# define __lzo_noreturn __declspec(noreturn)
-#endif
-#endif
-#if defined(__lzo_noreturn)
-# define __lzo_HAVE_noreturn 1
-#else
-# define __lzo_noreturn /*empty*/
-#endif
-#if !defined(__lzo_nothrow)
-#if (LZO_CC_GNUC >= 0x030300ul)
-# define __lzo_nothrow __attribute__((__nothrow__))
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus)
-# define __lzo_nothrow __declspec(nothrow)
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 900) && LZO_CC_SYNTAX_GNUC)
-# define __lzo_nothrow __attribute__((__nothrow__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_nothrow __attribute__((__nothrow__))
-#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus)
-# define __lzo_nothrow __declspec(nothrow)
-#endif
-#endif
-#if defined(__lzo_nothrow)
-# define __lzo_HAVE_nothrow 1
-#else
-# define __lzo_nothrow /*empty*/
-#endif
-#if !defined(__lzo_restrict)
-#if (LZO_CC_GNUC >= 0x030400ul)
-# define __lzo_restrict __restrict__
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
-# define __lzo_restrict __restrict__
-#elif (LZO_CC_CLANG || LZO_CC_LLVM)
-# define __lzo_restrict __restrict__
-#elif (LZO_CC_MSC && (_MSC_VER >= 1400))
-# define __lzo_restrict __restrict
-#endif
-#endif
-#if defined(__lzo_restrict)
-# define __lzo_HAVE_restrict 1
-#else
-# define __lzo_restrict /*empty*/
-#endif
-#if !defined(__lzo_likely) && !defined(__lzo_unlikely)
-#if (LZO_CC_GNUC >= 0x030200ul)
-# define __lzo_likely(e) (__builtin_expect(!!(e),1))
-# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800))
-# define __lzo_likely(e) (__builtin_expect(!!(e),1))
-# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_likely(e) (__builtin_expect(!!(e),1))
-# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
-#endif
-#endif
-#if defined(__lzo_likely)
-# define __lzo_HAVE_likely 1
-#else
-# define __lzo_likely(e) (e)
-#endif
-#if defined(__lzo_unlikely)
-# define __lzo_HAVE_unlikely 1
-#else
-# define __lzo_unlikely(e) (e)
-#endif
-#if !defined(LZO_UNUSED)
-# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
-# define LZO_UNUSED(var) ((void) &var)
-# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC)
-# define LZO_UNUSED(var) if (&var) ; else
-# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define LZO_UNUSED(var) ((void) var)
-# elif (LZO_CC_MSC && (_MSC_VER < 900))
-# define LZO_UNUSED(var) if (&var) ; else
-# elif (LZO_CC_KEILC)
-# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];}
-# elif (LZO_CC_PACIFICC)
-# define LZO_UNUSED(var) ((void) sizeof(var))
-# elif (LZO_CC_WATCOMC) && defined(__cplusplus)
-# define LZO_UNUSED(var) ((void) var)
-# else
-# define LZO_UNUSED(var) ((void) &var)
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
# endif
-#endif
-#if !defined(LZO_UNUSED_FUNC)
-# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
-# define LZO_UNUSED_FUNC(func) ((void) func)
-# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC)
-# define LZO_UNUSED_FUNC(func) if (func) ; else
-# elif (LZO_CC_CLANG || LZO_CC_LLVM)
-# define LZO_UNUSED_FUNC(func) ((void) &func)
-# elif (LZO_CC_MSC && (_MSC_VER < 900))
-# define LZO_UNUSED_FUNC(func) if (func) ; else
-# elif (LZO_CC_MSC)
-# define LZO_UNUSED_FUNC(func) ((void) &func)
-# elif (LZO_CC_KEILC || LZO_CC_PELLESC)
-# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];}
-# else
-# define LZO_UNUSED_FUNC(func) ((void) func)
+# ifndef LZO_OPT_UNALIGNED64
+# define LZO_OPT_UNALIGNED64 1
# endif
-#endif
-#if !defined(LZO_UNUSED_LABEL)
-# if (LZO_CC_WATCOMC) && defined(__cplusplus)
-# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
-# elif (LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC)
-# define LZO_UNUSED_LABEL(l) if (0) goto l
-# else
-# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
+#elif (LZO_ARCH_ARM)
+# if defined(__ARM_FEATURE_UNALIGNED)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
+# elif defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM+0) >= 7)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
+# elif defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM+0) >= 6) && !defined(__TARGET_PROFILE_M)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
# endif
-#endif
-#if !defined(LZO_DEFINE_UNINITIALIZED_VAR)
-# if 0
-# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var
-# elif 0 && (LZO_CC_GNUC)
-# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var
-# else
-# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init
+#elif (LZO_ARCH_ARM64)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
# endif
-#endif
-#if !defined(LZO_UNCONST_CAST)
-# if 0 && defined(__cplusplus)
-# define LZO_UNCONST_CAST(t,e) (const_cast<t> (e))
-# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((lzo_uintptr_t) ((const void *) (e))))))
-# else
-# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((const void *) (e)))))
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
# endif
-#endif
-#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER)
-# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC)
-# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)];
-# elif (LZO_CC_DMC || LZO_CC_SYMANTECC)
-# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)];
-# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
-# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)];
-# else
-# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)];
+# ifndef LZO_OPT_UNALIGNED64
+# define LZO_OPT_UNALIGNED64 1
# endif
-#endif
-#if !defined(LZO_COMPILE_TIME_ASSERT)
-# if (LZO_CC_AZTECC)
-# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];}
-# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
-# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
-# elif (LZO_CC_MSC && (_MSC_VER < 900))
-# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
-# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
-# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
-# else
-# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];}
+#elif (LZO_ARCH_CRIS)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
# endif
-#endif
-#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64)
-# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC)
-# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
-# define __lzo_cdecl __cdecl
-# define __lzo_cdecl_atexit /*empty*/
-# define __lzo_cdecl_main __cdecl
-# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
-# define __lzo_cdecl_qsort __pascal
-# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
-# define __lzo_cdecl_qsort _stdcall
-# else
-# define __lzo_cdecl_qsort __cdecl
-# endif
-# elif (LZO_CC_WATCOMC)
-# define __lzo_cdecl __cdecl
-# else
-# define __lzo_cdecl __cdecl
-# define __lzo_cdecl_atexit __cdecl
-# define __lzo_cdecl_main __cdecl
-# define __lzo_cdecl_qsort __cdecl
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
# endif
-# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC)
-# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
-# define __lzo_cdecl_sighandler __pascal
-# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
-# define __lzo_cdecl_sighandler _stdcall
-# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE)
-# define __lzo_cdecl_sighandler __clrcall
-# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700))
-# if defined(_DLL)
-# define __lzo_cdecl_sighandler _far _cdecl _loadds
-# elif defined(_MT)
-# define __lzo_cdecl_sighandler _far _cdecl
-# else
-# define __lzo_cdecl_sighandler _cdecl
-# endif
-# else
-# define __lzo_cdecl_sighandler __cdecl
+#elif (LZO_ARCH_I386)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
# endif
-#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC)
-# define __lzo_cdecl __cdecl
-#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC))
-# define __lzo_cdecl cdecl
-#endif
-#if !defined(__lzo_cdecl)
-# define __lzo_cdecl /*empty*/
-#endif
-#if !defined(__lzo_cdecl_atexit)
-# define __lzo_cdecl_atexit /*empty*/
-#endif
-#if !defined(__lzo_cdecl_main)
-# define __lzo_cdecl_main /*empty*/
-#endif
-#if !defined(__lzo_cdecl_qsort)
-# define __lzo_cdecl_qsort /*empty*/
-#endif
-#if !defined(__lzo_cdecl_sighandler)
-# define __lzo_cdecl_sighandler /*empty*/
-#endif
-#if !defined(__lzo_cdecl_va)
-# define __lzo_cdecl_va __lzo_cdecl
-#endif
-#if !(LZO_CFG_NO_WINDOWS_H)
-#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64)
-# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000))
-# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__)
-# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul)))
-# else
-# define LZO_HAVE_WINDOWS_H 1
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
# endif
-#endif
-#endif
-#if (LZO_ARCH_ALPHA)
-# define LZO_OPT_AVOID_UINT_INDEX 1
-# define LZO_OPT_AVOID_SHORT 1
-# define LZO_OPT_AVOID_USHORT 1
-#elif (LZO_ARCH_AMD64)
-# define LZO_OPT_AVOID_INT_INDEX 1
-# define LZO_OPT_AVOID_UINT_INDEX 1
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
-# define LZO_OPT_UNALIGNED64 1
-#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB)
-#elif (LZO_ARCH_ARM)
-# define LZO_OPT_AVOID_SHORT 1
-# define LZO_OPT_AVOID_USHORT 1
-#elif (LZO_ARCH_CRIS)
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
-#elif (LZO_ARCH_I386)
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
#elif (LZO_ARCH_IA64)
-# define LZO_OPT_AVOID_INT_INDEX 1
-# define LZO_OPT_AVOID_UINT_INDEX 1
-# define LZO_OPT_PREFER_POSTINC 1
+# define LZO_OPT_AVOID_INT_INDEX 1
+# define LZO_OPT_AVOID_UINT_INDEX 1
+# define LZO_OPT_PREFER_POSTINC 1
#elif (LZO_ARCH_M68K)
-# define LZO_OPT_PREFER_POSTINC 1
-# define LZO_OPT_PREFER_PREDEC 1
+# define LZO_OPT_PREFER_POSTINC 1
+# define LZO_OPT_PREFER_PREDEC 1
# if defined(__mc68020__) && !defined(__mcoldfire__)
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
# endif
#elif (LZO_ARCH_MIPS)
-# define LZO_OPT_AVOID_UINT_INDEX 1
+# define LZO_OPT_AVOID_UINT_INDEX 1
#elif (LZO_ARCH_POWERPC)
-# define LZO_OPT_PREFER_PREINC 1
-# define LZO_OPT_PREFER_PREDEC 1
+# define LZO_OPT_PREFER_PREINC 1
+# define LZO_OPT_PREFER_PREDEC 1
# if (LZO_ABI_BIG_ENDIAN)
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
+# if (LZO_WORDSIZE == 8)
+# ifndef LZO_OPT_UNALIGNED64
+# define LZO_OPT_UNALIGNED64 1
+# endif
+# endif
# endif
#elif (LZO_ARCH_S390)
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
-# if (LZO_SIZEOF_SIZE_T == 8)
-# define LZO_OPT_UNALIGNED64 1
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
+# if (LZO_WORDSIZE == 8)
+# ifndef LZO_OPT_UNALIGNED64
+# define LZO_OPT_UNALIGNED64 1
+# endif
# endif
#elif (LZO_ARCH_SH)
-# define LZO_OPT_PREFER_POSTINC 1
-# define LZO_OPT_PREFER_PREDEC 1
+# define LZO_OPT_PREFER_POSTINC 1
+# define LZO_OPT_PREFER_PREDEC 1
#endif
#ifndef LZO_CFG_NO_INLINE_ASM
-#if (LZO_CC_LLVM)
+#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC)
+# define LZO_CFG_NO_INLINE_ASM 1
+#elif (LZO_CC_LLVM)
# define LZO_CFG_NO_INLINE_ASM 1
#endif
#endif
+#if (LZO_CFG_NO_INLINE_ASM)
+# undef LZO_ASM_SYNTAX_MSC
+# undef LZO_ASM_SYNTAX_GNUC
+# undef __LZO_ASM_CLOBBER
+# undef __LZO_ASM_CLOBBER_LIST_CC
+# undef __LZO_ASM_CLOBBER_LIST_CC_MEMORY
+# undef __LZO_ASM_CLOBBER_LIST_EMPTY
+#endif
#ifndef LZO_CFG_NO_UNALIGNED
#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC)
# define LZO_CFG_NO_UNALIGNED 1
@@ -1784,25 +2574,6 @@ extern "C" {
# undef LZO_OPT_UNALIGNED32
# undef LZO_OPT_UNALIGNED64
#endif
-#if (LZO_CFG_NO_INLINE_ASM)
-#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
-# define LZO_ASM_SYNTAX_MSC 1
-#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
-#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul))
-#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
-# define LZO_ASM_SYNTAX_GNUC 1
-#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
-# define LZO_ASM_SYNTAX_GNUC 1
-#endif
-#if (LZO_ASM_SYNTAX_GNUC)
-#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul))
-# define __LZO_ASM_CLOBBER "ax"
-#elif (LZO_CC_INTELC)
-# define __LZO_ASM_CLOBBER "memory"
-#else
-# define __LZO_ASM_CLOBBER "cc", "memory"
-#endif
-#endif
#if defined(__LZO_INFOSTR_MM)
#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM))
# define __LZO_INFOSTR_MM ""
@@ -1846,7 +2617,382 @@ extern "C" {
#define LZO_INFO_STRING \
LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \
" " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER
+#if !(LZO_CFG_SKIP_LZO_TYPES)
+#if (!(LZO_SIZEOF_SHORT+0 > 0 && LZO_SIZEOF_INT+0 > 0 && LZO_SIZEOF_LONG+0 > 0))
+# error "missing defines for sizes"
+#endif
+#if (!(LZO_SIZEOF_PTRDIFF_T+0 > 0 && LZO_SIZEOF_SIZE_T+0 > 0 && LZO_SIZEOF_VOID_P+0 > 0))
+# error "missing defines for sizes"
+#endif
+#if !defined(lzo_llong_t)
+#if (LZO_SIZEOF_LONG_LONG+0 > 0)
+__lzo_gnuc_extension__ typedef long long lzo_llong_t__;
+__lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__;
+# define lzo_llong_t lzo_llong_t__
+# define lzo_ullong_t lzo_ullong_t__
+#endif
+#endif
+#if !defined(lzo_int16e_t)
+#if (LZO_SIZEOF_LONG == 2)
+# define lzo_int16e_t long
+# define lzo_uint16e_t unsigned long
+#elif (LZO_SIZEOF_INT == 2)
+# define lzo_int16e_t int
+# define lzo_uint16e_t unsigned int
+#elif (LZO_SIZEOF_SHORT == 2)
+# define lzo_int16e_t short int
+# define lzo_uint16e_t unsigned short int
+#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM)
+ typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__)));
+ typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__)));
+# define lzo_int16e_t lzo_int16e_hi_t__
+# define lzo_uint16e_t lzo_uint16e_hi_t__
+#elif (LZO_SIZEOF___INT16 == 2)
+# define lzo_int16e_t __int16
+# define lzo_uint16e_t unsigned __int16
+#else
+#endif
+#endif
+#if defined(lzo_int16e_t)
+# define LZO_SIZEOF_LZO_INT16E_T 2
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == 2)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == LZO_SIZEOF_LZO_INT16E_T)
+#endif
+#if !defined(lzo_int32e_t)
+#if (LZO_SIZEOF_LONG == 4)
+# define lzo_int32e_t long int
+# define lzo_uint32e_t unsigned long int
+#elif (LZO_SIZEOF_INT == 4)
+# define lzo_int32e_t int
+# define lzo_uint32e_t unsigned int
+#elif (LZO_SIZEOF_SHORT == 4)
+# define lzo_int32e_t short int
+# define lzo_uint32e_t unsigned short int
+#elif (LZO_SIZEOF_LONG_LONG == 4)
+# define lzo_int32e_t lzo_llong_t
+# define lzo_uint32e_t lzo_ullong_t
+#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L)
+ typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__)));
+ typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__)));
+# define lzo_int32e_t lzo_int32e_si_t__
+# define lzo_uint32e_t lzo_uint32e_si_t__
+#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L)
+ typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__)));
+ typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__)));
+# define lzo_int32e_t lzo_int32e_si_t__
+# define lzo_uint32e_t lzo_uint32e_si_t__
+# define LZO_INT32_C(c) (c##LL)
+# define LZO_UINT32_C(c) (c##ULL)
+#elif (LZO_SIZEOF___INT32 == 4)
+# define lzo_int32e_t __int32
+# define lzo_uint32e_t unsigned __int32
+#else
+#endif
+#endif
+#if defined(lzo_int32e_t)
+# define LZO_SIZEOF_LZO_INT32E_T 4
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == 4)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == LZO_SIZEOF_LZO_INT32E_T)
+#endif
+#if !defined(lzo_int64e_t)
+#if (LZO_SIZEOF___INT64 == 8)
+# if (LZO_CC_BORLANDC) && !(LZO_CFG_TYPE_PREFER___INT64)
+# define LZO_CFG_TYPE_PREFER___INT64 1
+# endif
+#endif
+#if (LZO_SIZEOF_INT == 8) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG)
+# define lzo_int64e_t int
+# define lzo_uint64e_t unsigned int
+# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_INT
+#elif (LZO_SIZEOF_LONG == 8)
+# define lzo_int64e_t long int
+# define lzo_uint64e_t unsigned long int
+# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG
+#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_TYPE_PREFER___INT64)
+# define lzo_int64e_t lzo_llong_t
+# define lzo_uint64e_t lzo_ullong_t
+# if (LZO_CC_BORLANDC)
+# define LZO_INT64_C(c) ((c) + 0ll)
+# define LZO_UINT64_C(c) ((c) + 0ull)
+# elif 0
+# define LZO_INT64_C(c) (__lzo_gnuc_extension__ (c##LL))
+# define LZO_UINT64_C(c) (__lzo_gnuc_extension__ (c##ULL))
+# else
+# define LZO_INT64_C(c) (c##LL)
+# define LZO_UINT64_C(c) (c##ULL)
+# endif
+# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG_LONG
+#elif (LZO_SIZEOF___INT64 == 8)
+# define lzo_int64e_t __int64
+# define lzo_uint64e_t unsigned __int64
+# if (LZO_CC_BORLANDC)
+# define LZO_INT64_C(c) ((c) + 0i64)
+# define LZO_UINT64_C(c) ((c) + 0ui64)
+# else
+# define LZO_INT64_C(c) (c##i64)
+# define LZO_UINT64_C(c) (c##ui64)
+# endif
+# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF___INT64
+#else
+#endif
+#endif
+#if defined(lzo_int64e_t)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == 8)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == LZO_SIZEOF_LZO_INT64E_T)
+#endif
+#if !defined(lzo_int32l_t)
+#if defined(lzo_int32e_t)
+# define lzo_int32l_t lzo_int32e_t
+# define lzo_uint32l_t lzo_uint32e_t
+# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LZO_INT32E_T
+#elif (LZO_SIZEOF_INT >= 4) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG)
+# define lzo_int32l_t int
+# define lzo_uint32l_t unsigned int
+# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_INT
+#elif (LZO_SIZEOF_LONG >= 4)
+# define lzo_int32l_t long int
+# define lzo_uint32l_t unsigned long int
+# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LONG
+#else
+# error "lzo_int32l_t"
+#endif
+#endif
+#if 1
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) >= 4)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) == LZO_SIZEOF_LZO_INT32L_T)
+#endif
+#if !defined(lzo_int64l_t)
+#if defined(lzo_int64e_t)
+# define lzo_int64l_t lzo_int64e_t
+# define lzo_uint64l_t lzo_uint64e_t
+# define LZO_SIZEOF_LZO_INT64L_T LZO_SIZEOF_LZO_INT64E_T
+#else
+#endif
+#endif
+#if defined(lzo_int64l_t)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) >= 8)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) == LZO_SIZEOF_LZO_INT64L_T)
+#endif
+#if !defined(lzo_int32f_t)
+#if (LZO_SIZEOF_SIZE_T >= 8)
+# define lzo_int32f_t lzo_int64l_t
+# define lzo_uint32f_t lzo_uint64l_t
+# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT64L_T
+#else
+# define lzo_int32f_t lzo_int32l_t
+# define lzo_uint32f_t lzo_uint32l_t
+# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT32L_T
+#endif
+#endif
+#if 1
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) >= 4)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) == LZO_SIZEOF_LZO_INT32F_T)
+#endif
+#if !defined(lzo_int64f_t)
+#if defined(lzo_int64l_t)
+# define lzo_int64f_t lzo_int64l_t
+# define lzo_uint64f_t lzo_uint64l_t
+# define LZO_SIZEOF_LZO_INT64F_T LZO_SIZEOF_LZO_INT64L_T
+#else
+#endif
+#endif
+#if defined(lzo_int64f_t)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) >= 8)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) == LZO_SIZEOF_LZO_INT64F_T)
+#endif
+#if !defined(lzo_intptr_t)
+#if 1 && (LZO_OS_OS400 && (LZO_SIZEOF_VOID_P == 16))
+# define __LZO_INTPTR_T_IS_POINTER 1
+ typedef char* lzo_intptr_t;
+ typedef char* lzo_uintptr_t;
+# define lzo_intptr_t lzo_intptr_t
+# define lzo_uintptr_t lzo_uintptr_t
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P
+#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4))
+ typedef __w64 int lzo_intptr_t;
+ typedef __w64 unsigned int lzo_uintptr_t;
+# define lzo_intptr_t lzo_intptr_t
+# define lzo_uintptr_t lzo_uintptr_t
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT
+#elif (LZO_SIZEOF_SHORT == LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT > LZO_SIZEOF_VOID_P)
+# define lzo_intptr_t short
+# define lzo_uintptr_t unsigned short
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_SHORT
+#elif (LZO_SIZEOF_INT >= LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG)
+# define lzo_intptr_t int
+# define lzo_uintptr_t unsigned int
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT
+#elif (LZO_SIZEOF_LONG >= LZO_SIZEOF_VOID_P)
+# define lzo_intptr_t long
+# define lzo_uintptr_t unsigned long
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LONG
+#elif (LZO_SIZEOF_LZO_INT64L_T >= LZO_SIZEOF_VOID_P)
+# define lzo_intptr_t lzo_int64l_t
+# define lzo_uintptr_t lzo_uint64l_t
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LZO_INT64L_T
+#else
+# error "lzo_intptr_t"
+#endif
+#endif
+#if 1
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) >= sizeof(void *))
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) == sizeof(lzo_uintptr_t))
+#endif
+#if !defined(lzo_word_t)
+#if defined(LZO_WORDSIZE) && (LZO_WORDSIZE+0 > 0)
+#if (LZO_WORDSIZE == LZO_SIZEOF_LZO_INTPTR_T) && !(__LZO_INTPTR_T_IS_POINTER)
+# define lzo_word_t lzo_uintptr_t
+# define lzo_sword_t lzo_intptr_t
+# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INTPTR_T
+#elif (LZO_WORDSIZE == LZO_SIZEOF_LONG)
+# define lzo_word_t unsigned long
+# define lzo_sword_t long
+# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LONG
+#elif (LZO_WORDSIZE == LZO_SIZEOF_INT)
+# define lzo_word_t unsigned int
+# define lzo_sword_t int
+# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_INT
+#elif (LZO_WORDSIZE == LZO_SIZEOF_SHORT)
+# define lzo_word_t unsigned short
+# define lzo_sword_t short
+# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_SHORT
+#elif (LZO_WORDSIZE == 1)
+# define lzo_word_t unsigned char
+# define lzo_sword_t signed char
+# define LZO_SIZEOF_LZO_WORD_T 1
+#elif (LZO_WORDSIZE == LZO_SIZEOF_LZO_INT64L_T)
+# define lzo_word_t lzo_uint64l_t
+# define lzo_sword_t lzo_int64l_t
+# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T
+#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC)
+#if 0
+ typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__)));
+ typedef int lzo_sword_t __attribute__((__mode__(__V16QI__)));
+# define lzo_word_t lzo_word_t
+# define lzo_sword_t lzo_sword_t
+# define LZO_SIZEOF_LZO_WORD_T 16
+#endif
+#else
+# error "lzo_word_t"
+#endif
+#endif
+#endif
+#if 1 && defined(lzo_word_t)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_word_t) == LZO_WORDSIZE)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_sword_t) == LZO_WORDSIZE)
+#endif
+#if 1
+#define lzo_int8_t signed char
+#define lzo_uint8_t unsigned char
+#define LZO_SIZEOF_LZO_INT8_T 1
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == sizeof(lzo_uint8_t))
+#endif
+#if defined(lzo_int16e_t)
+#define lzo_int16_t lzo_int16e_t
+#define lzo_uint16_t lzo_uint16e_t
+#define LZO_SIZEOF_LZO_INT16_T LZO_SIZEOF_LZO_INT16E_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == sizeof(lzo_uint16_t))
+#endif
+#if defined(lzo_int32e_t)
+#define lzo_int32_t lzo_int32e_t
+#define lzo_uint32_t lzo_uint32e_t
+#define LZO_SIZEOF_LZO_INT32_T LZO_SIZEOF_LZO_INT32E_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == sizeof(lzo_uint32_t))
+#endif
+#if defined(lzo_int64e_t)
+#define lzo_int64_t lzo_int64e_t
+#define lzo_uint64_t lzo_uint64e_t
+#define LZO_SIZEOF_LZO_INT64_T LZO_SIZEOF_LZO_INT64E_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == sizeof(lzo_uint64_t))
+#endif
+#if 1
+#define lzo_int_least32_t lzo_int32l_t
+#define lzo_uint_least32_t lzo_uint32l_t
+#define LZO_SIZEOF_LZO_INT_LEAST32_T LZO_SIZEOF_LZO_INT32L_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) >= 4)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) == sizeof(lzo_uint_least32_t))
+#endif
+#if defined(lzo_int64l_t)
+#define lzo_int_least64_t lzo_int64l_t
+#define lzo_uint_least64_t lzo_uint64l_t
+#define LZO_SIZEOF_LZO_INT_LEAST64_T LZO_SIZEOF_LZO_INT64L_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) >= 8)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) == sizeof(lzo_uint_least64_t))
+#endif
+#if 1
+#define lzo_int_fast32_t lzo_int32f_t
+#define lzo_uint_fast32_t lzo_uint32f_t
+#define LZO_SIZEOF_LZO_INT_FAST32_T LZO_SIZEOF_LZO_INT32F_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) >= 4)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) == sizeof(lzo_uint_fast32_t))
+#endif
+#if defined(lzo_int64f_t)
+#define lzo_int_fast64_t lzo_int64f_t
+#define lzo_uint_fast64_t lzo_uint64f_t
+#define LZO_SIZEOF_LZO_INT_FAST64_T LZO_SIZEOF_LZO_INT64F_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) >= 8)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) == sizeof(lzo_uint_fast64_t))
+#endif
+#if !defined(LZO_INT16_C)
+# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 2)
+# define LZO_INT16_C(c) ((c) + 0)
+# define LZO_UINT16_C(c) ((c) + 0U)
+# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 2)
+# define LZO_INT16_C(c) ((c) + 0L)
+# define LZO_UINT16_C(c) ((c) + 0UL)
+# elif (LZO_SIZEOF_INT >= 2)
+# define LZO_INT16_C(c) (c)
+# define LZO_UINT16_C(c) (c##U)
+# elif (LZO_SIZEOF_LONG >= 2)
+# define LZO_INT16_C(c) (c##L)
+# define LZO_UINT16_C(c) (c##UL)
+# else
+# error "LZO_INT16_C"
+# endif
+#endif
+#if !defined(LZO_INT32_C)
+# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 4)
+# define LZO_INT32_C(c) ((c) + 0)
+# define LZO_UINT32_C(c) ((c) + 0U)
+# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 4)
+# define LZO_INT32_C(c) ((c) + 0L)
+# define LZO_UINT32_C(c) ((c) + 0UL)
+# elif (LZO_SIZEOF_INT >= 4)
+# define LZO_INT32_C(c) (c)
+# define LZO_UINT32_C(c) (c##U)
+# elif (LZO_SIZEOF_LONG >= 4)
+# define LZO_INT32_C(c) (c##L)
+# define LZO_UINT32_C(c) (c##UL)
+# elif (LZO_SIZEOF_LONG_LONG >= 4)
+# define LZO_INT32_C(c) (c##LL)
+# define LZO_UINT32_C(c) (c##ULL)
+# else
+# error "LZO_INT32_C"
+# endif
+#endif
+#if !defined(LZO_INT64_C) && defined(lzo_int64l_t)
+# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 8)
+# define LZO_INT64_C(c) ((c) + 0)
+# define LZO_UINT64_C(c) ((c) + 0U)
+# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 8)
+# define LZO_INT64_C(c) ((c) + 0L)
+# define LZO_UINT64_C(c) ((c) + 0UL)
+# elif (LZO_SIZEOF_INT >= 8)
+# define LZO_INT64_C(c) (c)
+# define LZO_UINT64_C(c) (c##U)
+# elif (LZO_SIZEOF_LONG >= 8)
+# define LZO_INT64_C(c) (c##L)
+# define LZO_UINT64_C(c) (c##UL)
+# else
+# error "LZO_INT64_C"
+# endif
+#endif
+#endif
#endif /* already included */
-/* vim:set ts=4 et: */
+/* vim:set ts=4 sw=4 et: */
diff --git a/extern/lzo/minilzo/minilzo.c b/extern/lzo/minilzo/minilzo.c
index 34ce0f090bd..ab2be5f4fd0 100644
--- a/extern/lzo/minilzo/minilzo.c
+++ b/extern/lzo/minilzo/minilzo.c
@@ -2,22 +2,7 @@
This file is part of the LZO real-time data compression library.
- Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
@@ -67,12 +52,6 @@
#if defined(__CYGWIN32__) && !defined(__CYGWIN__)
# define __CYGWIN__ __CYGWIN32__
#endif
-#if defined(__IBMCPP__) && !defined(__IBMC__)
-# define __IBMC__ __IBMCPP__
-#endif
-#if defined(__ICL) && defined(_WIN32) && !defined(__INTEL_COMPILER)
-# define __INTEL_COMPILER __ICL
-#endif
#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE)
# define _ALL_SOURCE 1
#endif
@@ -81,19 +60,30 @@
# define __LONG_MAX__ 9223372036854775807L
# endif
#endif
-#if defined(__INTEL_COMPILER) && defined(__linux__)
+#if !defined(LZO_CFG_NO_DISABLE_WUNDEF)
+#if defined(__ARMCC_VERSION)
+# pragma diag_suppress 193
+#elif defined(__clang__) && defined(__clang_minor__)
+# pragma clang diagnostic ignored "-Wundef"
+#elif defined(__INTEL_COMPILER)
# pragma warning(disable: 193)
-#endif
-#if defined(__KEIL__) && defined(__C166__)
-# pragma warning disable = 322
-#elif 0 && defined(__C251__)
+#elif defined(__KEIL__) && defined(__C166__)
# pragma warning disable = 322
-#endif
-#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
-# if (_MSC_VER >= 1300)
+#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__PATHSCALE__)
+# if ((__GNUC__-0) >= 5 || ((__GNUC__-0) == 4 && (__GNUC_MINOR__-0) >= 2))
+# pragma GCC diagnostic ignored "-Wundef"
+# endif
+#elif defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__)
+# if ((_MSC_VER-0) >= 1300)
# pragma warning(disable: 4668)
# endif
#endif
+#endif
+#if 0 && defined(__POCC__) && defined(_WIN32)
+# if (__POCC__ >= 400)
+# pragma warn(disable: 2216)
+# endif
+#endif
#if 0 && defined(__WATCOMC__)
# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060)
# pragma warning 203 9
@@ -102,13 +92,29 @@
#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__)
# pragma option -h
#endif
+#if !(LZO_CFG_NO_DISABLE_WCRTNONSTDC)
+#ifndef _CRT_NONSTDC_NO_DEPRECATE
+#define _CRT_NONSTDC_NO_DEPRECATE 1
+#endif
+#ifndef _CRT_NONSTDC_NO_WARNINGS
+#define _CRT_NONSTDC_NO_WARNINGS 1
+#endif
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS 1
+#endif
+#endif
#if 0
-#define LZO_0xffffL 0xfffful
-#define LZO_0xffffffffL 0xfffffffful
+#define LZO_0xffffUL 0xfffful
+#define LZO_0xffffffffUL 0xfffffffful
#else
-#define LZO_0xffffL 65535ul
-#define LZO_0xffffffffL 4294967295ul
+#define LZO_0xffffUL 65535ul
+#define LZO_0xffffffffUL 4294967295ul
#endif
+#define LZO_0xffffL LZO_0xffffUL
+#define LZO_0xffffffffL LZO_0xffffffffUL
#if (LZO_0xffffL == LZO_0xffffffffL)
# error "your preprocessor is broken 1"
#endif
@@ -123,6 +129,13 @@
# error "your preprocessor is broken 4"
#endif
#endif
+#if defined(__COUNTER__)
+# ifndef LZO_CFG_USE_COUNTER
+# define LZO_CFG_USE_COUNTER 1
+# endif
+#else
+# undef LZO_CFG_USE_COUNTER
+#endif
#if (UINT_MAX == LZO_0xffffL)
#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__)
# if !defined(MSDOS)
@@ -253,14 +266,31 @@
#endif
#define LZO_PP_STRINGIZE(x) #x
#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x)
+#define LZO_PP_CONCAT0() /*empty*/
+#define LZO_PP_CONCAT1(a) a
#define LZO_PP_CONCAT2(a,b) a ## b
#define LZO_PP_CONCAT3(a,b,c) a ## b ## c
#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d
#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
+#define LZO_PP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f
+#define LZO_PP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g
+#define LZO_PP_ECONCAT0() LZO_PP_CONCAT0()
+#define LZO_PP_ECONCAT1(a) LZO_PP_CONCAT1(a)
#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b)
#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c)
#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d)
#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e)
+#define LZO_PP_ECONCAT6(a,b,c,d,e,f) LZO_PP_CONCAT6(a,b,c,d,e,f)
+#define LZO_PP_ECONCAT7(a,b,c,d,e,f,g) LZO_PP_CONCAT7(a,b,c,d,e,f,g)
+#define LZO_PP_EMPTY /*empty*/
+#define LZO_PP_EMPTY0() /*empty*/
+#define LZO_PP_EMPTY1(a) /*empty*/
+#define LZO_PP_EMPTY2(a,b) /*empty*/
+#define LZO_PP_EMPTY3(a,b,c) /*empty*/
+#define LZO_PP_EMPTY4(a,b,c,d) /*empty*/
+#define LZO_PP_EMPTY5(a,b,c,d,e) /*empty*/
+#define LZO_PP_EMPTY6(a,b,c,d,e,f) /*empty*/
+#define LZO_PP_EMPTY7(a,b,c,d,e,f,g) /*empty*/
#if 1
#define LZO_CPP_STRINGIZE(x) #x
#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x)
@@ -268,12 +298,16 @@
#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c
#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d
#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e
+#define LZO_CPP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f
+#define LZO_CPP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g
#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b)
#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c)
#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d)
#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e)
+#define LZO_CPP_ECONCAT6(a,b,c,d,e,f) LZO_CPP_CONCAT6(a,b,c,d,e,f)
+#define LZO_CPP_ECONCAT7(a,b,c,d,e,f,g) LZO_CPP_CONCAT7(a,b,c,d,e,f,g)
#endif
-#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-1)) - (o)) << 1) + (o))
+#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-!!(b))) - (o)) << 1) + (o)*!!(b))
#if 1 && defined(__cplusplus)
# if !defined(__STDC_CONSTANT_MACROS)
# define __STDC_CONSTANT_MACROS 1
@@ -283,9 +317,13 @@
# endif
#endif
#if defined(__cplusplus)
-# define LZO_EXTERN_C extern "C"
+# define LZO_EXTERN_C extern "C"
+# define LZO_EXTERN_C_BEGIN extern "C" {
+# define LZO_EXTERN_C_END }
#else
-# define LZO_EXTERN_C extern
+# define LZO_EXTERN_C extern
+# define LZO_EXTERN_C_BEGIN /*empty*/
+# define LZO_EXTERN_C_END /*empty*/
#endif
#if !defined(__LZO_OS_OVERRIDE)
#if (LZO_OS_FREESTANDING)
@@ -386,12 +424,12 @@
#elif defined(__VMS)
# define LZO_OS_VMS 1
# define LZO_INFO_OS "vms"
-#elif ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__))
+#elif (defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)
# define LZO_OS_CONSOLE 1
# define LZO_OS_CONSOLE_PS2 1
# define LZO_INFO_OS "console"
# define LZO_INFO_OS_CONSOLE "ps2"
-#elif (defined(__mips__) && defined(__psp__))
+#elif defined(__mips__) && defined(__psp__)
# define LZO_OS_CONSOLE 1
# define LZO_OS_CONSOLE_PSP 1
# define LZO_INFO_OS "console"
@@ -419,9 +457,18 @@
# elif defined(__linux__) || defined(__linux) || defined(__LINUX__)
# define LZO_OS_POSIX_LINUX 1
# define LZO_INFO_OS_POSIX "linux"
-# elif defined(__APPLE__) || defined(__MACOS__)
-# define LZO_OS_POSIX_MACOSX 1
-# define LZO_INFO_OS_POSIX "macosx"
+# elif defined(__APPLE__) && defined(__MACH__)
+# if ((__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__-0) >= 20000)
+# define LZO_OS_POSIX_DARWIN 1040
+# define LZO_INFO_OS_POSIX "darwin_iphone"
+# elif ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1040)
+# define LZO_OS_POSIX_DARWIN __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
+# define LZO_INFO_OS_POSIX "darwin"
+# else
+# define LZO_OS_POSIX_DARWIN 1
+# define LZO_INFO_OS_POSIX "darwin"
+# endif
+# define LZO_OS_POSIX_MACOSX LZO_OS_POSIX_DARWIN
# elif defined(__minix__) || defined(__minix)
# define LZO_OS_POSIX_MINIX 1
# define LZO_INFO_OS_POSIX "minix"
@@ -456,18 +503,18 @@
#endif
#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
# if (UINT_MAX != LZO_0xffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
# if (ULONG_MAX != LZO_0xffffffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
#endif
#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64)
# if (UINT_MAX != LZO_0xffffffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
# if (ULONG_MAX != LZO_0xffffffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
#endif
#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__)
@@ -483,59 +530,65 @@
# define LZO_INFO_CC "sdcc"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC)
#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__)
-# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + __PATHCC_MINOR__ * 0x100 + __PATHCC_PATCHLEVEL__)
+# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + (__PATHCC_MINOR__-0) * 0x100 + (__PATHCC_PATCHLEVEL__-0))
# define LZO_INFO_CC "Pathscale C"
# define LZO_INFO_CCVER __PATHSCALE__
-#elif defined(__INTEL_COMPILER)
-# define LZO_CC_INTELC 1
+# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# define LZO_CC_PATHSCALE_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
+# endif
+#elif defined(__INTEL_COMPILER) && ((__INTEL_COMPILER-0) > 0)
+# define LZO_CC_INTELC __INTEL_COMPILER
# define LZO_INFO_CC "Intel C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER)
-# if defined(_WIN32) || defined(_WIN64)
-# define LZO_CC_SYNTAX_MSC 1
-# else
-# define LZO_CC_SYNTAX_GNUC 1
+# if defined(_MSC_VER) && ((_MSC_VER-0) > 0)
+# define LZO_CC_INTELC_MSC _MSC_VER
+# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# define LZO_CC_INTELC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
# endif
#elif defined(__POCC__) && defined(_WIN32)
# define LZO_CC_PELLESC 1
# define LZO_INFO_CC "Pelles C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__)
-#elif defined(__clang__) && defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
# if defined(__GNUC_PATCHLEVEL__)
-# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
# else
-# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100)
# endif
+# define LZO_CC_ARMCC __ARMCC_VERSION
+# define LZO_INFO_CC "ARM C Compiler"
+# define LZO_INFO_CCVER __VERSION__
+#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__)
# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__)
-# define LZO_CC_CLANG_CLANG (__clang_major__ * 0x10000L + __clang_minor__ * 0x100 + __clang_patchlevel__)
+# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0))
# else
-# define LZO_CC_CLANG_CLANG 0x010000L
+# define LZO_CC_CLANG 0x010000L
+# endif
+# if defined(_MSC_VER) && ((_MSC_VER-0) > 0)
+# define LZO_CC_CLANG_MSC _MSC_VER
+# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
# endif
-# define LZO_CC_CLANG LZO_CC_CLANG_GNUC
# define LZO_INFO_CC "clang"
# define LZO_INFO_CCVER __VERSION__
#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
# if defined(__GNUC_PATCHLEVEL__)
-# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
+# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
# else
-# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
+# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100)
# endif
# define LZO_CC_LLVM LZO_CC_LLVM_GNUC
# define LZO_INFO_CC "llvm-gcc"
# define LZO_INFO_CCVER __VERSION__
-#elif defined(__GNUC__) && defined(__VERSION__)
-# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
-# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100 + __GNUC_PATCHLEVEL__)
-# elif defined(__GNUC_MINOR__)
-# define LZO_CC_GNUC (__GNUC__ * 0x10000L + __GNUC_MINOR__ * 0x100)
-# else
-# define LZO_CC_GNUC (__GNUC__ * 0x10000L)
-# endif
-# define LZO_INFO_CC "gcc"
-# define LZO_INFO_CCVER __VERSION__
#elif defined(__ACK__) && defined(_ACK)
# define LZO_CC_ACK 1
# define LZO_INFO_CC "Amsterdam Compiler Kit C"
# define LZO_INFO_CCVER "unknown"
+#elif defined(__ARMCC_VERSION) && !defined(__GNUC__)
+# define LZO_CC_ARMCC __ARMCC_VERSION
+# define LZO_CC_ARMCC_ARMCC __ARMCC_VERSION
+# define LZO_INFO_CC "ARM C Compiler"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ARMCC_VERSION)
#elif defined(__AZTEC_C__)
# define LZO_CC_AZTECC 1
# define LZO_INFO_CC "Aztec C"
@@ -560,10 +613,23 @@
# define LZO_CC_DECC 1
# define LZO_INFO_CC "DEC C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC)
+#elif (defined(__ghs) || defined(__ghs__)) && defined(__GHS_VERSION_NUMBER) && ((__GHS_VERSION_NUMBER-0) > 0)
+# define LZO_CC_GHS 1
+# define LZO_INFO_CC "Green Hills C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__GHS_VERSION_NUMBER)
+# if defined(_MSC_VER) && ((_MSC_VER-0) > 0)
+# define LZO_CC_GHS_MSC _MSC_VER
+# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__)
+# define LZO_CC_GHS_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
+# endif
#elif defined(__HIGHC__)
# define LZO_CC_HIGHC 1
# define LZO_INFO_CC "MetaWare High C"
# define LZO_INFO_CCVER "unknown"
+#elif defined(__HP_aCC) && ((__HP_aCC-0) > 0)
+# define LZO_CC_HPACC __HP_aCC
+# define LZO_INFO_CC "HP aCC"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__HP_aCC)
#elif defined(__IAR_SYSTEMS_ICC__)
# define LZO_CC_IARC 1
# define LZO_INFO_CC "IAR C"
@@ -572,10 +638,14 @@
# else
# define LZO_INFO_CCVER "unknown"
# endif
-#elif defined(__IBMC__)
-# define LZO_CC_IBMC 1
+#elif defined(__IBMC__) && ((__IBMC__-0) > 0)
+# define LZO_CC_IBMC __IBMC__
# define LZO_INFO_CC "IBM C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__)
+#elif defined(__IBMCPP__) && ((__IBMCPP__-0) > 0)
+# define LZO_CC_IBMC __IBMCPP__
+# define LZO_INFO_CC "IBM C"
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMCPP__)
#elif defined(__KEIL__) && defined(__C166__)
# define LZO_CC_KEILC 1
# define LZO_INFO_CC "Keil C"
@@ -592,16 +662,8 @@
# else
# define LZO_INFO_CCVER "unknown"
# endif
-#elif defined(_MSC_VER)
-# define LZO_CC_MSC 1
-# define LZO_INFO_CC "Microsoft C"
-# if defined(_MSC_FULL_VER)
-# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER)
-# else
-# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER)
-# endif
-#elif defined(__MWERKS__)
-# define LZO_CC_MWERKS 1
+#elif defined(__MWERKS__) && ((__MWERKS__-0) > 0)
+# define LZO_CC_MWERKS __MWERKS__
# define LZO_INFO_CC "Metrowerks C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__)
#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386)
@@ -612,6 +674,15 @@
# define LZO_CC_PACIFICC 1
# define LZO_INFO_CC "Pacific C"
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__)
+#elif defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__)
+# if defined(__PGIC_PATCHLEVEL__)
+# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100 + (__PGIC_PATCHLEVEL__-0))
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) "." LZO_PP_MACRO_EXPAND(__PGIC_PATCHLEVEL__)
+# else
+# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) ".0"
+# endif
+# define LZO_INFO_CC "Portland Group PGI C"
#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__))
# define LZO_CC_PGI 1
# define LZO_INFO_CC "Portland Group PGI C"
@@ -626,7 +697,7 @@
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__)
#elif defined(__SUNPRO_C)
# define LZO_INFO_CC "SunPro C"
-# if ((__SUNPRO_C)+0 > 0)
+# if ((__SUNPRO_C-0) > 0)
# define LZO_CC_SUNPROC __SUNPRO_C
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C)
# else
@@ -635,7 +706,7 @@
# endif
#elif defined(__SUNPRO_CC)
# define LZO_INFO_CC "SunPro C"
-# if ((__SUNPRO_CC)+0 > 0)
+# if ((__SUNPRO_CC-0) > 0)
# define LZO_CC_SUNPROC __SUNPRO_CC
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC)
# else
@@ -661,16 +732,46 @@
#elif defined(__ZTC__)
# define LZO_CC_ZORTECHC 1
# define LZO_INFO_CC "Zortech C"
-# if (__ZTC__ == 0x310)
+# if ((__ZTC__-0) == 0x310)
# define LZO_INFO_CCVER "0x310"
# else
# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__)
# endif
+#elif defined(__GNUC__) && defined(__VERSION__)
+# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__)
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0))
+# elif defined(__GNUC_MINOR__)
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100)
+# else
+# define LZO_CC_GNUC (__GNUC__ * 0x10000L)
+# endif
+# define LZO_INFO_CC "gcc"
+# define LZO_INFO_CCVER __VERSION__
+#elif defined(_MSC_VER) && ((_MSC_VER-0) > 0)
+# define LZO_CC_MSC _MSC_VER
+# define LZO_INFO_CC "Microsoft C"
+# if defined(_MSC_FULL_VER)
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER)
+# else
+# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER)
+# endif
#else
# define LZO_CC_UNKNOWN 1
# define LZO_INFO_CC "unknown"
# define LZO_INFO_CCVER "unknown"
#endif
+#if (LZO_CC_GNUC) && defined(__OPEN64__)
+# if defined(__OPENCC__) && defined(__OPENCC_MINOR__) && defined(__OPENCC_PATCHLEVEL__)
+# define LZO_CC_OPEN64 (__OPENCC__ * 0x10000L + (__OPENCC_MINOR__-0) * 0x100 + (__OPENCC_PATCHLEVEL__-0))
+# define LZO_CC_OPEN64_GNUC LZO_CC_GNUC
+# endif
+#endif
+#if (LZO_CC_GNUC) && defined(__PCC__)
+# if defined(__PCC__) && defined(__PCC_MINOR__) && defined(__PCC_MINORMINOR__)
+# define LZO_CC_PCC (__PCC__ * 0x10000L + (__PCC_MINOR__-0) * 0x100 + (__PCC_MINORMINOR__-0))
+# define LZO_CC_PCC_GNUC LZO_CC_GNUC
+# endif
+#endif
#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER)
# error "LZO_CC_MSC: _MSC_FULL_VER is not defined"
#endif
@@ -688,8 +789,10 @@
# define LZO_INFO_ARCH "generic"
#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
# define LZO_ARCH_I086 1
-# define LZO_ARCH_IA16 1
# define LZO_INFO_ARCH "i086"
+#elif defined(__aarch64__)
+# define LZO_ARCH_ARM64 1
+# define LZO_INFO_ARCH "arm64"
#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA)
# define LZO_ARCH_ALPHA 1
# define LZO_INFO_ARCH "alpha"
@@ -705,10 +808,10 @@
# define LZO_INFO_ARCH "arm_thumb"
#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__)
# define LZO_ARCH_ARM 1
-# if defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 1)
+# if defined(__CPU_MODE__) && ((__CPU_MODE__-0) == 1)
# define LZO_ARCH_ARM_THUMB 1
# define LZO_INFO_ARCH "arm_thumb"
-# elif defined(__CPU_MODE__) && ((__CPU_MODE__)+0 == 2)
+# elif defined(__CPU_MODE__) && ((__CPU_MODE__-0) == 2)
# define LZO_INFO_ARCH "arm"
# else
# define LZO_INFO_ARCH "arm"
@@ -826,53 +929,147 @@
# error "FIXME - missing define for CPU architecture"
#endif
#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32)
-# error "FIXME - missing WIN32 define for CPU architecture"
+# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture"
#endif
#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64)
-# error "FIXME - missing WIN64 define for CPU architecture"
+# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture"
#endif
#if (LZO_OS_OS216 || LZO_OS_WIN16)
# define LZO_ARCH_I086PM 1
-# define LZO_ARCH_IA16PM 1
#elif 1 && (LZO_OS_DOS16 && defined(BLX286))
# define LZO_ARCH_I086PM 1
-# define LZO_ARCH_IA16PM 1
#elif 1 && (LZO_OS_DOS16 && defined(DOSX286))
# define LZO_ARCH_I086PM 1
-# define LZO_ARCH_IA16PM 1
#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__))
# define LZO_ARCH_I086PM 1
-# define LZO_ARCH_IA16PM 1
#endif
-#if (LZO_ARCH_ARM_THUMB) && !(LZO_ARCH_ARM)
-# error "this should not happen"
+#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64)
+# define LZO_ARCH_X64 1
+#elif (!LZO_ARCH_AMD64 && LZO_ARCH_X64) && defined(__LZO_ARCH_OVERRIDE)
+# define LZO_ARCH_AMD64 1
+#endif
+#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64)
+# define LZO_ARCH_AARCH64 1
+#elif (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) && defined(__LZO_ARCH_OVERRIDE)
+# define LZO_ARCH_ARM64 1
+#endif
+#if (LZO_ARCH_I386 && !LZO_ARCH_X86)
+# define LZO_ARCH_X86 1
+#elif (!LZO_ARCH_I386 && LZO_ARCH_X86) && defined(__LZO_ARCH_OVERRIDE)
+# define LZO_ARCH_I386 1
+#endif
+#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) || (!LZO_ARCH_AMD64 && LZO_ARCH_X64)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) || (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_I386 && !LZO_ARCH_X86) || (!LZO_ARCH_I386 && LZO_ARCH_X86)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM_THUMB && !LZO_ARCH_ARM)
+# error "unexpected configuration - check your compiler defines"
#endif
-#if (LZO_ARCH_I086PM) && !(LZO_ARCH_I086)
-# error "this should not happen"
+#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM_THUMB)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM_THUMB)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM_THUMB1 && LZO_ARCH_ARM_THUMB2)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_I086PM && !LZO_ARCH_I086)
+# error "unexpected configuration - check your compiler defines"
#endif
#if (LZO_ARCH_I086)
# if (UINT_MAX != LZO_0xffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
# if (ULONG_MAX != LZO_0xffffffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
#endif
#if (LZO_ARCH_I386)
# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
# if (ULONG_MAX != LZO_0xffffffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
+# endif
+#endif
+#if (LZO_ARCH_AMD64 || LZO_ARCH_I386)
+# if !defined(LZO_TARGET_FEATURE_SSE2)
+# if defined(__SSE2__)
+# define LZO_TARGET_FEATURE_SSE2 1
+# elif defined(_MSC_VER) && ((defined(_M_IX86_FP) && ((_M_IX86_FP)+0 >= 2)) || defined(_M_AMD64))
+# define LZO_TARGET_FEATURE_SSE2 1
+# endif
+# endif
+# if !defined(LZO_TARGET_FEATURE_SSSE3)
+# if (LZO_TARGET_FEATURE_SSE2)
+# if defined(__SSSE3__)
+# define LZO_TARGET_FEATURE_SSSE3 1
+# elif defined(_MSC_VER) && defined(__AVX__)
+# define LZO_TARGET_FEATURE_SSSE3 1
+# endif
+# endif
+# endif
+# if !defined(LZO_TARGET_FEATURE_SSE4_2)
+# if (LZO_TARGET_FEATURE_SSSE3)
+# if defined(__SSE4_2__)
+# define LZO_TARGET_FEATURE_SSE4_2 1
+# endif
+# endif
+# endif
+# if !defined(LZO_TARGET_FEATURE_AVX)
+# if (LZO_TARGET_FEATURE_SSSE3)
+# if defined(__AVX__)
+# define LZO_TARGET_FEATURE_AVX 1
+# endif
+# endif
+# endif
+# if !defined(LZO_TARGET_FEATURE_AVX2)
+# if (LZO_TARGET_FEATURE_AVX)
+# if defined(__AVX2__)
+# define LZO_TARGET_FEATURE_AVX2 1
+# endif
+# endif
+# endif
+#endif
+#if (LZO_TARGET_FEATURE_SSSE3 && !(LZO_TARGET_FEATURE_SSE2))
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_TARGET_FEATURE_SSE4_2 && !(LZO_TARGET_FEATURE_SSSE3))
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_TARGET_FEATURE_AVX && !(LZO_TARGET_FEATURE_SSSE3))
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_TARGET_FEATURE_AVX2 && !(LZO_TARGET_FEATURE_AVX))
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if (LZO_ARCH_ARM)
+# if !defined(LZO_TARGET_FEATURE_NEON)
+# if defined(__ARM_NEON__)
+# define LZO_TARGET_FEATURE_NEON 1
+# endif
+# endif
+#elif (LZO_ARCH_ARM64)
+# if !defined(LZO_TARGET_FEATURE_NEON)
+# if 1
+# define LZO_TARGET_FEATURE_NEON 1
+# endif
# endif
#endif
-#if !defined(__LZO_MM_OVERRIDE)
+#if 0
+#elif !defined(__LZO_MM_OVERRIDE)
#if (LZO_ARCH_I086)
#if (UINT_MAX != LZO_0xffffL)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
#endif
#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM)
# define LZO_MM_TINY 1
@@ -899,7 +1096,7 @@
#elif (LZO_CC_ZORTECHC && defined(__VCM__))
# define LZO_MM_LARGE 1
#else
-# error "unknown memory model"
+# error "unknown LZO_ARCH_I086 memory model"
#endif
#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
#define LZO_HAVE_MM_HUGE_PTR 1
@@ -922,10 +1119,10 @@
#endif
#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR)
# if (LZO_OS_DOS16)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# elif (LZO_CC_ZORTECHC)
# else
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
# endif
#endif
#ifdef __cplusplus
@@ -957,7 +1154,7 @@ extern "C" {
#endif
#elif (LZO_ARCH_C166)
#if !defined(__MODEL__)
-# error "FIXME - C166 __MODEL__"
+# error "FIXME - LZO_ARCH_C166 __MODEL__"
#elif ((__MODEL__) == 0)
# define LZO_MM_SMALL 1
#elif ((__MODEL__) == 1)
@@ -971,11 +1168,11 @@ extern "C" {
#elif ((__MODEL__) == 5)
# define LZO_MM_XSMALL 1
#else
-# error "FIXME - C166 __MODEL__"
+# error "FIXME - LZO_ARCH_C166 __MODEL__"
#endif
#elif (LZO_ARCH_MCS251)
#if !defined(__MODEL__)
-# error "FIXME - MCS251 __MODEL__"
+# error "FIXME - LZO_ARCH_MCS251 __MODEL__"
#elif ((__MODEL__) == 0)
# define LZO_MM_SMALL 1
#elif ((__MODEL__) == 2)
@@ -987,11 +1184,11 @@ extern "C" {
#elif ((__MODEL__) == 5)
# define LZO_MM_XSMALL 1
#else
-# error "FIXME - MCS251 __MODEL__"
+# error "FIXME - LZO_ARCH_MCS251 __MODEL__"
#endif
#elif (LZO_ARCH_MCS51)
#if !defined(__MODEL__)
-# error "FIXME - MCS51 __MODEL__"
+# error "FIXME - LZO_ARCH_MCS51 __MODEL__"
#elif ((__MODEL__) == 1)
# define LZO_MM_SMALL 1
#elif ((__MODEL__) == 2)
@@ -1003,7 +1200,7 @@ extern "C" {
#elif ((__MODEL__) == 5)
# define LZO_MM_XSMALL 1
#else
-# error "FIXME - MCS51 __MODEL__"
+# error "FIXME - LZO_ARCH_MCS51 __MODEL__"
#endif
#elif (LZO_ARCH_CRAY_PVP)
# define LZO_MM_PVP 1
@@ -1030,35 +1227,818 @@ extern "C" {
# error "unknown memory model"
#endif
#endif
+#if !defined(__lzo_gnuc_extension__)
+#if (LZO_CC_GNUC >= 0x020800ul)
+# define __lzo_gnuc_extension__ __extension__
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_gnuc_extension__ __extension__
+#elif (LZO_CC_IBMC >= 600)
+# define __lzo_gnuc_extension__ __extension__
+#else
+#endif
+#endif
+#if !defined(__lzo_gnuc_extension__)
+# define __lzo_gnuc_extension__ /*empty*/
+#endif
+#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) && defined(__cplusplus) && 0
+# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul))
+# define LZO_CFG_USE_NEW_STYLE_CASTS 0
+# elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1200))
+# define LZO_CFG_USE_NEW_STYLE_CASTS 0
+# else
+# define LZO_CFG_USE_NEW_STYLE_CASTS 1
+# endif
+#endif
+#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_CFG_USE_NEW_STYLE_CASTS 0
+#endif
+#if !defined(__cplusplus)
+# if defined(LZO_CFG_USE_NEW_STYLE_CASTS)
+# undef LZO_CFG_USE_NEW_STYLE_CASTS
+# endif
+# define LZO_CFG_USE_NEW_STYLE_CASTS 0
+#endif
+#if !defined(LZO_REINTERPRET_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_REINTERPRET_CAST(t,e) (reinterpret_cast<t> (e))
+# endif
+#endif
+#if !defined(LZO_REINTERPRET_CAST)
+# define LZO_REINTERPRET_CAST(t,e) ((t) (e))
+#endif
+#if !defined(LZO_STATIC_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_STATIC_CAST(t,e) (static_cast<t> (e))
+# endif
+#endif
+#if !defined(LZO_STATIC_CAST)
+# define LZO_STATIC_CAST(t,e) ((t) (e))
+#endif
+#if !defined(LZO_STATIC_CAST2)
+# define LZO_STATIC_CAST2(t1,t2,e) LZO_STATIC_CAST(t1, LZO_STATIC_CAST(t2, e))
+#endif
+#if !defined(LZO_UNCONST_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_UNCONST_CAST(t,e) (const_cast<t> (e))
+# elif (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_UNCONST_CAST(t,e) ((t) (e))
+# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((const void *) (e)))))
+# endif
+#endif
+#if !defined(LZO_UNCONST_CAST)
+# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e))))
+#endif
+#if !defined(LZO_UNCONST_VOLATILE_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_UNCONST_VOLATILE_CAST(t,e) (const_cast<t> (e))
+# elif (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) (e))
+# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((lzo_uintptr_t) ((volatile const void *) (e)))))
+# endif
+#endif
+#if !defined(LZO_UNCONST_VOLATILE_CAST)
+# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((volatile const void *) (e))))
+#endif
+#if !defined(LZO_UNVOLATILE_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_UNVOLATILE_CAST(t,e) (const_cast<t> (e))
+# elif (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_UNVOLATILE_CAST(t,e) ((t) (e))
+# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((volatile void *) (e)))))
+# endif
+#endif
+#if !defined(LZO_UNVOLATILE_CAST)
+# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((volatile void *) (e))))
+#endif
+#if !defined(LZO_UNVOLATILE_CONST_CAST)
+# if (LZO_CFG_USE_NEW_STYLE_CASTS)
+# define LZO_UNVOLATILE_CONST_CAST(t,e) (const_cast<t> (e))
+# elif (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) (e))
+# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((lzo_uintptr_t) ((volatile const void *) (e)))))
+# endif
+#endif
+#if !defined(LZO_UNVOLATILE_CONST_CAST)
+# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e))))
+#endif
+#if !defined(LZO_PCAST)
+# if (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_PCAST(t,e) ((t) (e))
+# endif
+#endif
+#if !defined(LZO_PCAST)
+# define LZO_PCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(void *, e))
+#endif
+#if !defined(LZO_CCAST)
+# if (LZO_HAVE_MM_HUGE_PTR)
+# define LZO_CCAST(t,e) ((t) (e))
+# endif
+#endif
+#if !defined(LZO_CCAST)
+# define LZO_CCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(const void *, e))
+#endif
+#if !defined(LZO_ICONV)
+# define LZO_ICONV(t,e) LZO_STATIC_CAST(t, e)
+#endif
+#if !defined(LZO_ICAST)
+# define LZO_ICAST(t,e) LZO_STATIC_CAST(t, e)
+#endif
+#if !defined(LZO_ITRUNC)
+# define LZO_ITRUNC(t,e) LZO_STATIC_CAST(t, e)
+#endif
+#if !defined(__lzo_cte)
+# if (LZO_CC_MSC || LZO_CC_WATCOMC)
+# define __lzo_cte(e) ((void)0,(e))
+# elif 1
+# define __lzo_cte(e) ((void)0,(e))
+# endif
+#endif
+#if !defined(__lzo_cte)
+# define __lzo_cte(e) (e)
+#endif
+#if !defined(LZO_BLOCK_BEGIN)
+# define LZO_BLOCK_BEGIN do {
+# define LZO_BLOCK_END } while __lzo_cte(0)
+#endif
+#if !defined(LZO_UNUSED)
+# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
+# define LZO_UNUSED(var) ((void) &var)
+# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC)
+# define LZO_UNUSED(var) if (&var) ; else
+# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030200ul))
+# define LZO_UNUSED(var) ((void) &var)
+# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define LZO_UNUSED(var) ((void) var)
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_UNUSED(var) if (&var) ; else
+# elif (LZO_CC_KEILC)
+# define LZO_UNUSED(var) {LZO_EXTERN_C int lzo_unused__[1-2*!(sizeof(var)>0)];}
+# elif (LZO_CC_PACIFICC)
+# define LZO_UNUSED(var) ((void) sizeof(var))
+# elif (LZO_CC_WATCOMC) && defined(__cplusplus)
+# define LZO_UNUSED(var) ((void) var)
+# else
+# define LZO_UNUSED(var) ((void) &var)
+# endif
+#endif
+#if !defined(LZO_UNUSED_FUNC)
+# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
+# define LZO_UNUSED_FUNC(func) ((void) func)
+# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC)
+# define LZO_UNUSED_FUNC(func) if (func) ; else
+# elif (LZO_CC_CLANG || LZO_CC_LLVM)
+# define LZO_UNUSED_FUNC(func) ((void) &func)
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_UNUSED_FUNC(func) if (func) ; else
+# elif (LZO_CC_MSC)
+# define LZO_UNUSED_FUNC(func) ((void) &func)
+# elif (LZO_CC_KEILC || LZO_CC_PELLESC)
+# define LZO_UNUSED_FUNC(func) {LZO_EXTERN_C int lzo_unused_func__[1-2*!(sizeof((int)func)>0)];}
+# else
+# define LZO_UNUSED_FUNC(func) ((void) func)
+# endif
+#endif
+#if !defined(LZO_UNUSED_LABEL)
+# if (LZO_CC_CLANG >= 0x020800ul)
+# define LZO_UNUSED_LABEL(l) (__lzo_gnuc_extension__ ((void) ((const void *) &&l)))
+# elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC)
+# define LZO_UNUSED_LABEL(l) if __lzo_cte(0) goto l
+# else
+# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l
+# endif
+#endif
+#if !defined(LZO_DEFINE_UNINITIALIZED_VAR)
+# if 0
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var
+# elif 0 && (LZO_CC_GNUC)
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var
+# else
+# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init
+# endif
+#endif
+#if !defined(__lzo_inline)
+#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295))
+#elif defined(__cplusplus)
+# define __lzo_inline inline
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L)
+# define __lzo_inline inline
+#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550))
+# define __lzo_inline __inline
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+# define __lzo_inline __inline__
+#elif (LZO_CC_DMC)
+# define __lzo_inline __inline
+#elif (LZO_CC_GHS)
+# define __lzo_inline __inline__
+#elif (LZO_CC_IBMC >= 600)
+# define __lzo_inline __inline__
+#elif (LZO_CC_INTELC)
+# define __lzo_inline __inline
+#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405))
+# define __lzo_inline __inline
+#elif (LZO_CC_MSC && (_MSC_VER >= 900))
+# define __lzo_inline __inline
+#elif (LZO_CC_SUNPROC >= 0x5100)
+# define __lzo_inline __inline__
+#endif
+#endif
+#if defined(__lzo_inline)
+# ifndef __lzo_HAVE_inline
+# define __lzo_HAVE_inline 1
+# endif
+#else
+# define __lzo_inline /*empty*/
+#endif
+#if !defined(__lzo_forceinline)
+#if (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_IBMC >= 700)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450))
+# define __lzo_forceinline __forceinline
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800))
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
+# define __lzo_forceinline __forceinline
+#elif (LZO_CC_PGI >= 0x0d0a00ul)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#elif (LZO_CC_SUNPROC >= 0x5100)
+# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+#endif
+#endif
+#if defined(__lzo_forceinline)
+# ifndef __lzo_HAVE_forceinline
+# define __lzo_HAVE_forceinline 1
+# endif
+#else
+# define __lzo_forceinline __lzo_inline
+#endif
+#if !defined(__lzo_noinline)
+#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul)
+# define __lzo_noinline __attribute__((__noinline__,__used__))
+#elif (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_IBMC >= 700)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600))
+# define __lzo_noinline __declspec(noinline)
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800))
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_noinline __declspec(noinline)
+#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64))
+# if defined(__cplusplus)
+# else
+# define __lzo_noinline __declspec(noinline)
+# endif
+#elif (LZO_CC_PGI >= 0x0d0a00ul)
+# define __lzo_noinline __attribute__((__noinline__))
+#elif (LZO_CC_SUNPROC >= 0x5100)
+# define __lzo_noinline __attribute__((__noinline__))
+#endif
+#endif
+#if defined(__lzo_noinline)
+# ifndef __lzo_HAVE_noinline
+# define __lzo_HAVE_noinline 1
+# endif
+#else
+# define __lzo_noinline /*empty*/
+#endif
+#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if !defined(__lzo_static_inline)
+#if (LZO_CC_IBMC)
+# define __lzo_static_inline __lzo_gnuc_extension__ static __lzo_inline
+#endif
+#endif
+#if !defined(__lzo_static_inline)
+# define __lzo_static_inline static __lzo_inline
+#endif
+#if !defined(__lzo_static_forceinline)
+#if (LZO_CC_IBMC)
+# define __lzo_static_forceinline __lzo_gnuc_extension__ static __lzo_forceinline
+#endif
+#endif
+#if !defined(__lzo_static_forceinline)
+# define __lzo_static_forceinline static __lzo_forceinline
+#endif
+#if !defined(__lzo_static_noinline)
+#if (LZO_CC_IBMC)
+# define __lzo_static_noinline __lzo_gnuc_extension__ static __lzo_noinline
+#endif
+#endif
+#if !defined(__lzo_static_noinline)
+# define __lzo_static_noinline static __lzo_noinline
+#endif
+#if !defined(__lzo_c99_extern_inline)
+#if defined(__GNUC_GNU_INLINE__)
+# define __lzo_c99_extern_inline __lzo_inline
+#elif defined(__GNUC_STDC_INLINE__)
+# define __lzo_c99_extern_inline extern __lzo_inline
+#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L)
+# define __lzo_c99_extern_inline extern __lzo_inline
+#endif
+#if !defined(__lzo_c99_extern_inline) && (__lzo_HAVE_inline)
+# define __lzo_c99_extern_inline __lzo_inline
+#endif
+#endif
+#if defined(__lzo_c99_extern_inline)
+# ifndef __lzo_HAVE_c99_extern_inline
+# define __lzo_HAVE_c99_extern_inline 1
+# endif
+#else
+# define __lzo_c99_extern_inline /*empty*/
+#endif
+#if !defined(__lzo_may_alias)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_may_alias __attribute__((__may_alias__))
+#elif (LZO_CC_CLANG >= 0x020900ul)
+# define __lzo_may_alias __attribute__((__may_alias__))
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1210)) && 0
+# define __lzo_may_alias __attribute__((__may_alias__))
+#elif (LZO_CC_PGI >= 0x0d0a00ul) && 0
+# define __lzo_may_alias __attribute__((__may_alias__))
+#endif
+#endif
+#if defined(__lzo_may_alias)
+# ifndef __lzo_HAVE_may_alias
+# define __lzo_HAVE_may_alias 1
+# endif
+#else
+# define __lzo_may_alias /*empty*/
+#endif
+#if !defined(__lzo_noreturn)
+#if (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_IBMC >= 700)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450))
+# define __lzo_noreturn __declspec(noreturn)
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600))
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
+# define __lzo_noreturn __declspec(noreturn)
+#elif (LZO_CC_PGI >= 0x0d0a00ul)
+# define __lzo_noreturn __attribute__((__noreturn__))
+#endif
+#endif
+#if defined(__lzo_noreturn)
+# ifndef __lzo_HAVE_noreturn
+# define __lzo_HAVE_noreturn 1
+# endif
+#else
+# define __lzo_noreturn /*empty*/
+#endif
+#if !defined(__lzo_nothrow)
+#if (LZO_CC_GNUC >= 0x030300ul)
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) && defined(__cplusplus)
+# define __lzo_nothrow __declspec(nothrow)
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 900))
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_nothrow __attribute__((__nothrow__))
+#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus)
+# define __lzo_nothrow __declspec(nothrow)
+#endif
+#endif
+#if defined(__lzo_nothrow)
+# ifndef __lzo_HAVE_nothrow
+# define __lzo_HAVE_nothrow 1
+# endif
+#else
+# define __lzo_nothrow /*empty*/
+#endif
+#if !defined(__lzo_restrict)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_IBMC >= 800) && !defined(__cplusplus)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_IBMC >= 1210)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600))
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600))
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM)
+# define __lzo_restrict __restrict__
+#elif (LZO_CC_MSC && (_MSC_VER >= 1400))
+# define __lzo_restrict __restrict
+#elif (LZO_CC_PGI >= 0x0d0a00ul)
+# define __lzo_restrict __restrict__
+#endif
+#endif
+#if defined(__lzo_restrict)
+# ifndef __lzo_HAVE_restrict
+# define __lzo_HAVE_restrict 1
+# endif
+#else
+# define __lzo_restrict /*empty*/
+#endif
+#if !defined(__lzo_alignof)
+#if (LZO_CC_ARMCC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+# define __lzo_alignof(e) __alignof__(e)
+#elif (LZO_CC_GHS) && !defined(__cplusplus)
+# define __lzo_alignof(e) __alignof__(e)
+#elif (LZO_CC_IBMC >= 600)
+# define __lzo_alignof(e) (__lzo_gnuc_extension__ __alignof__(e))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700))
+# define __lzo_alignof(e) __alignof__(e)
+#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_alignof(e) __alignof(e)
+#elif (LZO_CC_SUNPROC >= 0x5100)
+# define __lzo_alignof(e) __alignof__(e)
+#endif
+#endif
+#if defined(__lzo_alignof)
+# ifndef __lzo_HAVE_alignof
+# define __lzo_HAVE_alignof 1
+# endif
+#endif
+#if !defined(__lzo_struct_packed)
+#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus)
+#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul))
+#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus)
+#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul))
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus)
+#elif (LZO_CC_GNUC >= 0x030400ul) && !(LZO_CC_PCC_GNUC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386)
+# define __lzo_struct_packed(s) struct s {
+# define __lzo_struct_packed_end() } __attribute__((__gcc_struct__,__packed__));
+# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__gcc_struct__,__packed__));
+#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_struct_packed(s) struct s {
+# define __lzo_struct_packed_end() } __attribute__((__packed__));
+# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__));
+#elif (LZO_CC_IBMC >= 700)
+# define __lzo_struct_packed(s) __lzo_gnuc_extension__ struct s {
+# define __lzo_struct_packed_end() } __attribute__((__packed__));
+# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__));
+#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_struct_packed(s) __pragma(pack(push,1)) struct s {
+# define __lzo_struct_packed_end() } __pragma(pack(pop));
+#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900))
+# define __lzo_struct_packed(s) _Packed struct s {
+# define __lzo_struct_packed_end() };
+#endif
+#endif
+#if defined(__lzo_struct_packed) && !defined(__lzo_struct_packed_ma)
+# define __lzo_struct_packed_ma(s) __lzo_struct_packed(s)
+#endif
+#if defined(__lzo_struct_packed_end) && !defined(__lzo_struct_packed_ma_end)
+# define __lzo_struct_packed_ma_end() __lzo_struct_packed_end()
+#endif
+#if !defined(__lzo_byte_struct)
+#if defined(__lzo_struct_packed)
+# define __lzo_byte_struct(s,n) __lzo_struct_packed(s) unsigned char a[n]; __lzo_struct_packed_end()
+# define __lzo_byte_struct_ma(s,n) __lzo_struct_packed_ma(s) unsigned char a[n]; __lzo_struct_packed_ma_end()
+#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_PGI || (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_byte_struct(s,n) struct s { unsigned char a[n]; } __attribute__((__packed__));
+# define __lzo_byte_struct_ma(s,n) struct s { unsigned char a[n]; } __lzo_may_alias __attribute__((__packed__));
+#endif
+#endif
+#if defined(__lzo_byte_struct) && !defined(__lzo_byte_struct_ma)
+# define __lzo_byte_struct_ma(s,n) __lzo_byte_struct(s,n)
+#endif
+#if !defined(__lzo_struct_align16) && (__lzo_HAVE_alignof)
+#if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul))
+#elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus)
+#elif (LZO_CC_CILLY || LZO_CC_PCC)
+#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_struct_align16(s) struct __declspec(align(16)) s {
+# define __lzo_struct_align16_end() };
+# define __lzo_struct_align32(s) struct __declspec(align(32)) s {
+# define __lzo_struct_align32_end() };
+# define __lzo_struct_align64(s) struct __declspec(align(64)) s {
+# define __lzo_struct_align64_end() };
+#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || (LZO_CC_IBMC >= 700) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_struct_align16(s) struct s {
+# define __lzo_struct_align16_end() } __attribute__((__aligned__(16)));
+# define __lzo_struct_align32(s) struct s {
+# define __lzo_struct_align32_end() } __attribute__((__aligned__(32)));
+# define __lzo_struct_align64(s) struct s {
+# define __lzo_struct_align64_end() } __attribute__((__aligned__(64)));
+#endif
+#endif
+#if !defined(__lzo_union_um)
+#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus)
+#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul))
+#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus)
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER < 810))
+#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul))
+#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus)
+#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100))
+# define __lzo_union_am(s) union s {
+# define __lzo_union_am_end() } __lzo_may_alias;
+# define __lzo_union_um(s) union s {
+# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__));
+#elif (LZO_CC_IBMC >= 700)
+# define __lzo_union_am(s) __lzo_gnuc_extension__ union s {
+# define __lzo_union_am_end() } __lzo_may_alias;
+# define __lzo_union_um(s) __lzo_gnuc_extension__ union s {
+# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__));
+#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300))
+# define __lzo_union_um(s) __pragma(pack(push,1)) union s {
+# define __lzo_union_um_end() } __pragma(pack(pop));
+#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900))
+# define __lzo_union_um(s) _Packed union s {
+# define __lzo_union_um_end() };
+#endif
+#endif
+#if !defined(__lzo_union_am)
+# define __lzo_union_am(s) union s {
+# define __lzo_union_am_end() };
+#endif
+#if !defined(__lzo_constructor)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_constructor __attribute__((__constructor__,__used__))
+#elif (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_constructor __attribute__((__constructor__))
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800))
+# define __lzo_constructor __attribute__((__constructor__,__used__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_constructor __attribute__((__constructor__))
+#endif
+#endif
+#if defined(__lzo_constructor)
+# ifndef __lzo_HAVE_constructor
+# define __lzo_HAVE_constructor 1
+# endif
+#endif
+#if !defined(__lzo_destructor)
+#if (LZO_CC_GNUC >= 0x030400ul)
+# define __lzo_destructor __attribute__((__destructor__,__used__))
+#elif (LZO_CC_GNUC >= 0x020700ul)
+# define __lzo_destructor __attribute__((__destructor__))
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800))
+# define __lzo_destructor __attribute__((__destructor__,__used__))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_destructor __attribute__((__destructor__))
+#endif
+#endif
+#if defined(__lzo_destructor)
+# ifndef __lzo_HAVE_destructor
+# define __lzo_HAVE_destructor 1
+# endif
+#endif
+#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor)
+# error "unexpected configuration - check your compiler defines"
+#endif
+#if !defined(__lzo_likely) && !defined(__lzo_unlikely)
+#if (LZO_CC_GNUC >= 0x030200ul)
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#elif (LZO_CC_IBMC >= 1010)
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800))
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+# define __lzo_likely(e) (__builtin_expect(!!(e),1))
+# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
+#endif
+#endif
+#if defined(__lzo_likely)
+# ifndef __lzo_HAVE_likely
+# define __lzo_HAVE_likely 1
+# endif
+#else
+# define __lzo_likely(e) (e)
+#endif
+#if defined(__lzo_unlikely)
+# ifndef __lzo_HAVE_unlikely
+# define __lzo_HAVE_unlikely 1
+# endif
+#else
+# define __lzo_unlikely(e) (e)
+#endif
+#if !defined(__lzo_static_unused_void_func)
+# if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+# define __lzo_static_unused_void_func(f) static void __attribute__((__unused__)) f(void)
+# else
+# define __lzo_static_unused_void_func(f) static __lzo_inline void f(void)
+# endif
+#endif
+#if !defined(__lzo_loop_forever)
+# if (LZO_CC_IBMC)
+# define __lzo_loop_forever() LZO_BLOCK_BEGIN for (;;) { ; } LZO_BLOCK_END
+# else
+# define __lzo_loop_forever() do { ; } while __lzo_cte(1)
+# endif
+#endif
+#if !defined(__lzo_unreachable)
+#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x020800ul))
+# define __lzo_unreachable() __builtin_unreachable();
+#elif (LZO_CC_GNUC >= 0x040500ul)
+# define __lzo_unreachable() __builtin_unreachable();
+#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1300)) && 1
+# define __lzo_unreachable() __builtin_unreachable();
+#endif
+#endif
+#if defined(__lzo_unreachable)
+# ifndef __lzo_HAVE_unreachable
+# define __lzo_HAVE_unreachable 1
+# endif
+#else
+# if 0
+# define __lzo_unreachable() ((void)0);
+# else
+# define __lzo_unreachable() __lzo_loop_forever();
+# endif
+#endif
+#ifndef __LZO_CTA_NAME
+#if (LZO_CFG_USE_COUNTER)
+# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__COUNTER__)
+#else
+# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__LINE__)
+#endif
+#endif
+#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER)
+# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END
+# elif (LZO_CC_DMC || LZO_CC_SYMANTECC)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1u-2*!(e)]; LZO_EXTERN_C_END
+# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END
+# elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020900ul)) && defined(__cplusplus)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN int __LZO_CTA_NAME(lzo_cta_f__)(int [1-2*!(e)]); LZO_EXTERN_C_END
+# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__)); LZO_EXTERN_C_END
+# else
+# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-2*!(e)]; LZO_EXTERN_C_END
+# endif
+#endif
+#if !defined(LZO_COMPILE_TIME_ASSERT)
+# if (LZO_CC_AZTECC)
+# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-!(e)];}
+# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__)
+# define LZO_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));}
+# elif (LZO_CC_GNUC >= 0x040700ul) && (LZO_CFG_USE_COUNTER) && defined(__cplusplus)
+# define LZO_COMPILE_TIME_ASSERT(e) {enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__));}
+# elif (LZO_CC_GNUC >= 0x040700ul)
+# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));}
+# elif (LZO_CC_MSC && (_MSC_VER < 900))
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
+# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
+# else
+# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)];}
+# endif
+#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(1 == 1)
+#if defined(__cplusplus)
+extern "C" { LZO_COMPILE_TIME_ASSERT_HEADER(2 == 2) }
+#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(3 == 3)
+#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64)
+# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC)
+# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
+# define __lzo_cdecl __cdecl
+# define __lzo_cdecl_atexit /*empty*/
+# define __lzo_cdecl_main __cdecl
+# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
+# define __lzo_cdecl_qsort __pascal
+# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
+# define __lzo_cdecl_qsort _stdcall
+# else
+# define __lzo_cdecl_qsort __cdecl
+# endif
+# elif (LZO_CC_WATCOMC)
+# define __lzo_cdecl __cdecl
+# else
+# define __lzo_cdecl __cdecl
+# define __lzo_cdecl_atexit __cdecl
+# define __lzo_cdecl_main __cdecl
+# define __lzo_cdecl_qsort __cdecl
+# endif
+# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC)
+# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
+# define __lzo_cdecl_sighandler __pascal
+# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
+# define __lzo_cdecl_sighandler _stdcall
+# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE)
+# define __lzo_cdecl_sighandler __clrcall
+# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700))
+# if defined(_DLL)
+# define __lzo_cdecl_sighandler _far _cdecl _loadds
+# elif defined(_MT)
+# define __lzo_cdecl_sighandler _far _cdecl
+# else
+# define __lzo_cdecl_sighandler _cdecl
+# endif
+# else
+# define __lzo_cdecl_sighandler __cdecl
+# endif
+#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC)
+# define __lzo_cdecl __cdecl
+#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC))
+# define __lzo_cdecl cdecl
+#endif
+#if !defined(__lzo_cdecl)
+# define __lzo_cdecl /*empty*/
+#endif
+#if !defined(__lzo_cdecl_atexit)
+# define __lzo_cdecl_atexit /*empty*/
+#endif
+#if !defined(__lzo_cdecl_main)
+# define __lzo_cdecl_main /*empty*/
+#endif
+#if !defined(__lzo_cdecl_qsort)
+# define __lzo_cdecl_qsort /*empty*/
+#endif
+#if !defined(__lzo_cdecl_sighandler)
+# define __lzo_cdecl_sighandler /*empty*/
+#endif
+#if !defined(__lzo_cdecl_va)
+# define __lzo_cdecl_va __lzo_cdecl
+#endif
+#if !(LZO_CFG_NO_WINDOWS_H)
+#if !defined(LZO_HAVE_WINDOWS_H)
+#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64)
+# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000))
+# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__)
+# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul)))
+# else
+# define LZO_HAVE_WINDOWS_H 1
+# endif
+#endif
+#endif
+#endif
+#ifndef LZO_SIZEOF_SHORT
#if defined(SIZEOF_SHORT)
# define LZO_SIZEOF_SHORT (SIZEOF_SHORT)
+#elif defined(__SIZEOF_SHORT__)
+# define LZO_SIZEOF_SHORT (__SIZEOF_SHORT__)
+#endif
#endif
+#ifndef LZO_SIZEOF_INT
#if defined(SIZEOF_INT)
# define LZO_SIZEOF_INT (SIZEOF_INT)
+#elif defined(__SIZEOF_INT__)
+# define LZO_SIZEOF_INT (__SIZEOF_INT__)
#endif
+#endif
+#ifndef LZO_SIZEOF_LONG
#if defined(SIZEOF_LONG)
# define LZO_SIZEOF_LONG (SIZEOF_LONG)
+#elif defined(__SIZEOF_LONG__)
+# define LZO_SIZEOF_LONG (__SIZEOF_LONG__)
+#endif
#endif
+#ifndef LZO_SIZEOF_LONG_LONG
#if defined(SIZEOF_LONG_LONG)
# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG)
+#elif defined(__SIZEOF_LONG_LONG__)
+# define LZO_SIZEOF_LONG_LONG (__SIZEOF_LONG_LONG__)
+#endif
#endif
+#ifndef LZO_SIZEOF___INT16
#if defined(SIZEOF___INT16)
# define LZO_SIZEOF___INT16 (SIZEOF___INT16)
#endif
+#endif
+#ifndef LZO_SIZEOF___INT32
#if defined(SIZEOF___INT32)
# define LZO_SIZEOF___INT32 (SIZEOF___INT32)
#endif
+#endif
+#ifndef LZO_SIZEOF___INT64
#if defined(SIZEOF___INT64)
# define LZO_SIZEOF___INT64 (SIZEOF___INT64)
#endif
+#endif
+#ifndef LZO_SIZEOF_VOID_P
#if defined(SIZEOF_VOID_P)
# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P)
+#elif defined(__SIZEOF_POINTER__)
+# define LZO_SIZEOF_VOID_P (__SIZEOF_POINTER__)
#endif
+#endif
+#ifndef LZO_SIZEOF_SIZE_T
#if defined(SIZEOF_SIZE_T)
# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T)
+#elif defined(__SIZEOF_SIZE_T__)
+# define LZO_SIZEOF_SIZE_T (__SIZEOF_SIZE_T__)
+#endif
#endif
+#ifndef LZO_SIZEOF_PTRDIFF_T
#if defined(SIZEOF_PTRDIFF_T)
# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T)
+#elif defined(__SIZEOF_PTRDIFF_T__)
+# define LZO_SIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__)
+#endif
#endif
#define __LZO_LSR(x,b) (((x)+0ul) >> (b))
#if !defined(LZO_SIZEOF_SHORT)
@@ -1080,6 +2060,7 @@ extern "C" {
# error "LZO_SIZEOF_SHORT"
# endif
#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SHORT == sizeof(short))
#if !defined(LZO_SIZEOF_INT)
# if (LZO_ARCH_CRAY_PVP)
# define LZO_SIZEOF_INT 8
@@ -1101,6 +2082,7 @@ extern "C" {
# error "LZO_SIZEOF_INT"
# endif
#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_INT == sizeof(int))
#if !defined(LZO_SIZEOF_LONG)
# if (ULONG_MAX == LZO_0xffffffffL)
# define LZO_SIZEOF_LONG 4
@@ -1110,6 +2092,8 @@ extern "C" {
# define LZO_SIZEOF_LONG 2
# elif (__LZO_LSR(ULONG_MAX,31) == 1)
# define LZO_SIZEOF_LONG 4
+# elif (__LZO_LSR(ULONG_MAX,39) == 1)
+# define LZO_SIZEOF_LONG 5
# elif (__LZO_LSR(ULONG_MAX,63) == 1)
# define LZO_SIZEOF_LONG 8
# elif (__LZO_LSR(ULONG_MAX,127) == 1)
@@ -1118,11 +2102,12 @@ extern "C" {
# error "LZO_SIZEOF_LONG"
# endif
#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_LONG == sizeof(long))
#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64)
#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8)
# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__)
# if (LZO_CC_GNUC >= 0x030300ul)
-# if ((__LONG_MAX__)+0 == (__LONG_LONG_MAX__)+0)
+# if ((__LONG_MAX__-0) == (__LONG_LONG_MAX__-0))
# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG
# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1)
# define LZO_SIZEOF_LONG_LONG 4
@@ -1136,7 +2121,7 @@ extern "C" {
#if (LZO_ARCH_I086 && LZO_CC_DMC)
#elif (LZO_CC_CILLY) && defined(__GNUC__)
# define LZO_SIZEOF_LONG_LONG 8
-#elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
+#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
# define LZO_SIZEOF_LONG_LONG 8
#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400))
# define LZO_SIZEOF_LONG_LONG 8
@@ -1158,11 +2143,13 @@ extern "C" {
# define LZO_SIZEOF___INT64 8
#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100)))
# define LZO_SIZEOF___INT64 8
-#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && (_INTEGRAL_MAX_BITS == 64))
+#elif (LZO_CC_GHS && defined(__LLONG_BIT) && ((__LLONG_BIT-0) == 64))
+# define LZO_SIZEOF_LONG_LONG 8
+#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && ((_INTEGRAL_MAX_BITS-0) == 64))
# define LZO_SIZEOF___INT64 8
#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__)
# define LZO_SIZEOF_LONG_LONG 8
-#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64)
+#elif (defined(__vms) || defined(__VMS)) && ((__INITIAL_POINTER_SIZE-0) == 64)
# define LZO_SIZEOF_LONG_LONG 8
#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2)
#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
@@ -1175,87 +2162,127 @@ extern "C" {
# undef LZO_SIZEOF_LONG_LONG
# endif
#endif
-#if (LZO_CFG_NO_LONG_LONG) || defined(__NO_LONG_LONG)
+#if (LZO_CFG_NO_LONG_LONG)
+# undef LZO_SIZEOF_LONG_LONG
+#elif defined(__NO_LONG_LONG)
+# undef LZO_SIZEOF_LONG_LONG
+#elif defined(_NO_LONGLONG)
# undef LZO_SIZEOF_LONG_LONG
#endif
-#if !defined(LZO_SIZEOF_VOID_P)
-#if (LZO_ARCH_I086)
-# define __LZO_WORDSIZE 2
-# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM)
-# define LZO_SIZEOF_VOID_P 2
-# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE)
-# define LZO_SIZEOF_VOID_P 4
+#if !defined(LZO_WORDSIZE)
+#if (LZO_ARCH_ALPHA)
+# define LZO_WORDSIZE 8
+#elif (LZO_ARCH_AMD64)
+# define LZO_WORDSIZE 8
+#elif (LZO_ARCH_AVR)
+# define LZO_WORDSIZE 1
+#elif (LZO_ARCH_H8300)
+# if defined(__NORMAL_MODE__)
+# define LZO_WORDSIZE 4
+# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__)
+# define LZO_WORDSIZE 4
# else
-# error "LZO_MM"
+# define LZO_WORDSIZE 2
# endif
-#elif (LZO_ARCH_AVR || LZO_ARCH_Z80)
-# define __LZO_WORDSIZE 1
+#elif (LZO_ARCH_I086)
+# define LZO_WORDSIZE 2
+#elif (LZO_ARCH_IA64)
+# define LZO_WORDSIZE 8
+#elif (LZO_ARCH_M16C)
+# define LZO_WORDSIZE 2
+#elif (LZO_ARCH_SPU)
+# define LZO_WORDSIZE 4
+#elif (LZO_ARCH_Z80)
+# define LZO_WORDSIZE 1
+#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__))
+# define LZO_WORDSIZE 8
+#elif (LZO_OS_OS400 || defined(__OS400__))
+# define LZO_WORDSIZE 8
+#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64)
+# define LZO_WORDSIZE 8
+#endif
+#endif
+#if !defined(LZO_SIZEOF_VOID_P)
+#if defined(__ILP32__) || defined(__ILP32) || defined(_ILP32)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
+# define LZO_SIZEOF_VOID_P 4
+#elif defined(__ILP64__) || defined(__ILP64) || defined(_ILP64)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 8)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8)
+# define LZO_SIZEOF_VOID_P 8
+#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4)
+# define LZO_SIZEOF_VOID_P 8
+#elif defined(__LP64__) || defined(__LP64) || defined(_LP64)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8)
+# define LZO_SIZEOF_VOID_P 8
+#elif (LZO_ARCH_AVR)
# define LZO_SIZEOF_VOID_P 2
#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430)
# define LZO_SIZEOF_VOID_P 2
#elif (LZO_ARCH_H8300)
# if defined(__NORMAL_MODE__)
-# define __LZO_WORDSIZE 4
# define LZO_SIZEOF_VOID_P 2
# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__)
-# define __LZO_WORDSIZE 4
# define LZO_SIZEOF_VOID_P 4
# else
-# define __LZO_WORDSIZE 2
# define LZO_SIZEOF_VOID_P 2
# endif
# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4)
# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT
# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT
# endif
+#elif (LZO_ARCH_I086)
+# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM)
+# define LZO_SIZEOF_VOID_P 2
+# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE)
+# define LZO_SIZEOF_VOID_P 4
+# else
+# error "invalid LZO_ARCH_I086 memory model"
+# endif
#elif (LZO_ARCH_M16C)
-# define __LZO_WORDSIZE 2
# if defined(__m32c_cpu__) || defined(__m32cm_cpu__)
# define LZO_SIZEOF_VOID_P 4
# else
# define LZO_SIZEOF_VOID_P 2
# endif
+#elif (LZO_ARCH_SPU)
+# define LZO_SIZEOF_VOID_P 4
+#elif (LZO_ARCH_Z80)
+# define LZO_SIZEOF_VOID_P 2
#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__))
-# define __LZO_WORDSIZE 8
# define LZO_SIZEOF_VOID_P 4
-#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64)
-# define __LZO_WORDSIZE 8
-# define LZO_SIZEOF_VOID_P 8
-#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__)
-# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG
-# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
-# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
#elif (LZO_OS_OS400 || defined(__OS400__))
-# define __LZO_WORDSIZE LZO_SIZEOF_LONG
-# define LZO_SIZEOF_VOID_P 16
-# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
-# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+# if defined(__LLP64_IFC__)
+# define LZO_SIZEOF_VOID_P 8
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+# else
+# define LZO_SIZEOF_VOID_P 16
+# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
+# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
+# endif
#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64)
# define LZO_SIZEOF_VOID_P 8
# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG
# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG
-#elif (LZO_ARCH_SPU)
-# if 0
-# define __LZO_WORDSIZE 16
-# endif
-# define LZO_SIZEOF_VOID_P 4
-#else
-# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG
#endif
#endif
-#if !defined(LZO_WORDSIZE)
-# if defined(__LZO_WORDSIZE)
-# define LZO_WORDSIZE __LZO_WORDSIZE
-# else
-# define LZO_WORDSIZE LZO_SIZEOF_VOID_P
-# endif
+#if !defined(LZO_SIZEOF_VOID_P)
+# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG
#endif
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_VOID_P == sizeof(void *))
#if !defined(LZO_SIZEOF_SIZE_T)
#if (LZO_ARCH_I086 || LZO_ARCH_M16C)
# define LZO_SIZEOF_SIZE_T 2
-#else
+#endif
+#endif
+#if !defined(LZO_SIZEOF_SIZE_T)
# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P
#endif
+#if defined(offsetof)
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SIZE_T == sizeof(size_t))
#endif
#if !defined(LZO_SIZEOF_PTRDIFF_T)
#if (LZO_ARCH_I086)
@@ -1268,11 +2295,18 @@ extern "C" {
# define LZO_SIZEOF_PTRDIFF_T 2
# endif
# else
-# error "LZO_MM"
+# error "invalid LZO_ARCH_I086 memory model"
# endif
-#else
+#endif
+#endif
+#if !defined(LZO_SIZEOF_PTRDIFF_T)
# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T
#endif
+#if defined(offsetof)
+LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t))
+#endif
+#if !defined(LZO_WORDSIZE)
+# define LZO_WORDSIZE LZO_SIZEOF_VOID_P
#endif
#if (LZO_ABI_NEUTRAL_ENDIAN)
# undef LZO_ABI_BIG_ENDIAN
@@ -1284,7 +2318,7 @@ extern "C" {
# define LZO_ABI_LITTLE_ENDIAN 1
#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430)
# define LZO_ABI_LITTLE_ENDIAN 1
-#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390)
+#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390 || LZO_ARCH_SPU)
# define LZO_ABI_BIG_ENDIAN 1
#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__)
# if (__LITTLE_ENDIAN__ == 1)
@@ -1300,6 +2334,19 @@ extern "C" {
# define LZO_ABI_BIG_ENDIAN 1
#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__)
# define LZO_ABI_LITTLE_ENDIAN 1
+#elif 1 && (LZO_ARCH_ARM && LZO_CC_ARMCC_ARMCC)
+# if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN)
+# error "unexpected configuration - check your compiler defines"
+# elif defined(__BIG_ENDIAN)
+# define LZO_ABI_BIG_ENDIAN 1
+# else
+# define LZO_ABI_LITTLE_ENDIAN 1
+# endif
+# define LZO_ABI_LITTLE_ENDIAN 1
+#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EB__) && !defined(__AARCH64EL__)
+# define LZO_ABI_BIG_ENDIAN 1
+#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EL__) && !defined(__AARCH64EB__)
+# define LZO_ABI_LITTLE_ENDIAN 1
#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__)
# define LZO_ABI_BIG_ENDIAN 1
#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__)
@@ -1307,7 +2354,7 @@ extern "C" {
#endif
#endif
#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN)
-# error "this should not happen"
+# error "unexpected configuration - check your compiler defines"
#endif
#if (LZO_ABI_BIG_ENDIAN)
# define LZO_INFO_ABI_ENDIAN "be"
@@ -1322,6 +2369,9 @@ extern "C" {
#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2)
# define LZO_ABI_ILP16 1
# define LZO_INFO_ABI_PM "ilp16"
+#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4)
+# define LZO_ABI_LP32 1
+# define LZO_INFO_ABI_PM "lp32"
#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4)
# define LZO_ABI_ILP32 1
# define LZO_INFO_ABI_PM "ilp32"
@@ -1338,7 +2388,8 @@ extern "C" {
# define LZO_ABI_IP32L64 1
# define LZO_INFO_ABI_PM "ip32l64"
#endif
-#if !defined(__LZO_LIBC_OVERRIDE)
+#if 0
+#elif !defined(__LZO_LIBC_OVERRIDE)
#if (LZO_LIBC_NAKED)
# define LZO_INFO_LIBC "naked"
#elif (LZO_LIBC_FREESTANDING)
@@ -1349,6 +2400,9 @@ extern "C" {
# define LZO_INFO_LIBC "isoc90"
#elif (LZO_LIBC_ISOC99)
# define LZO_INFO_LIBC "isoc99"
+#elif (LZO_CC_ARMCC_ARMCC) && defined(__ARMCLIB_VERSION)
+# define LZO_LIBC_ISOC90 1
+# define LZO_INFO_LIBC "isoc90"
#elif defined(__dietlibc__)
# define LZO_LIBC_DIETLIBC 1
# define LZO_INFO_LIBC "dietlibc"
@@ -1357,13 +2411,13 @@ extern "C" {
# define LZO_INFO_LIBC "newlib"
#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__)
# if defined(__UCLIBC_SUBLEVEL__)
-# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + __UCLIBC_MINOR__ * 0x100 + __UCLIBC_SUBLEVEL__)
+# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + (__UCLIBC_MINOR__-0) * 0x100 + (__UCLIBC_SUBLEVEL__-0))
# else
# define LZO_LIBC_UCLIBC 0x00090bL
# endif
-# define LZO_INFO_LIBC "uclibc"
+# define LZO_INFO_LIBC "uc" "libc"
#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__)
-# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + __GLIBC_MINOR__ * 0x100)
+# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + (__GLIBC_MINOR__-0) * 0x100)
# define LZO_INFO_LIBC "glibc"
#elif (LZO_CC_MWERKS) && defined(__MSL__)
# define LZO_LIBC_MSL __MSL__
@@ -1376,424 +2430,160 @@ extern "C" {
# define LZO_INFO_LIBC "default"
#endif
#endif
-#if !defined(__lzo_gnuc_extension__)
-#if (LZO_CC_GNUC >= 0x020800ul)
-# define __lzo_gnuc_extension__ __extension__
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_gnuc_extension__ __extension__
-#else
-# define __lzo_gnuc_extension__ /*empty*/
-#endif
-#endif
-#if !defined(__lzo_ua_volatile)
-# define __lzo_ua_volatile volatile
-#endif
-#if !defined(__lzo_alignof)
-#if (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
-# define __lzo_alignof(e) __alignof__(e)
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700))
-# define __lzo_alignof(e) __alignof__(e)
-#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
-# define __lzo_alignof(e) __alignof(e)
-#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
-# define __lzo_alignof(e) __alignof__(e)
-#endif
-#endif
-#if defined(__lzo_alignof)
-# define __lzo_HAVE_alignof 1
-#endif
-#if !defined(__lzo_constructor)
-#if (LZO_CC_GNUC >= 0x030400ul)
-# define __lzo_constructor __attribute__((__constructor__,__used__))
-#elif (LZO_CC_GNUC >= 0x020700ul)
-# define __lzo_constructor __attribute__((__constructor__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_constructor __attribute__((__constructor__))
-#endif
-#endif
-#if defined(__lzo_constructor)
-# define __lzo_HAVE_constructor 1
-#endif
-#if !defined(__lzo_destructor)
-#if (LZO_CC_GNUC >= 0x030400ul)
-# define __lzo_destructor __attribute__((__destructor__,__used__))
-#elif (LZO_CC_GNUC >= 0x020700ul)
-# define __lzo_destructor __attribute__((__destructor__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_destructor __attribute__((__destructor__))
-#endif
-#endif
-#if defined(__lzo_destructor)
-# define __lzo_HAVE_destructor 1
-#endif
-#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor)
-# error "this should not happen"
-#endif
-#if !defined(__lzo_inline)
-#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295))
-#elif defined(__cplusplus)
-# define __lzo_inline inline
-#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550))
-# define __lzo_inline __inline
-#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
-# define __lzo_inline __inline__
-#elif (LZO_CC_DMC)
-# define __lzo_inline __inline
-#elif (LZO_CC_INTELC)
-# define __lzo_inline __inline
-#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405))
-# define __lzo_inline __inline
-#elif (LZO_CC_MSC && (_MSC_VER >= 900))
-# define __lzo_inline __inline
-#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
-# define __lzo_inline __inline__
-#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
-# define __lzo_inline inline
-#endif
+#if (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
+# define LZO_ASM_SYNTAX_MSC 1
+#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
+#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul))
+#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+# define LZO_ASM_SYNTAX_GNUC 1
+#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
+# define LZO_ASM_SYNTAX_GNUC 1
+#elif (LZO_CC_GNUC)
+# define LZO_ASM_SYNTAX_GNUC 1
#endif
-#if defined(__lzo_inline)
-# define __lzo_HAVE_inline 1
+#if (LZO_ASM_SYNTAX_GNUC)
+#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul))
+# define __LZO_ASM_CLOBBER "ax"
+# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/
+# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY /*empty*/
+# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/
+#elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1000))
+# define __LZO_ASM_CLOBBER "memory"
+# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/
+# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "memory"
+# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/
#else
-# define __lzo_inline /*empty*/
-#endif
-#if !defined(__lzo_forceinline)
-#if (LZO_CC_GNUC >= 0x030200ul)
-# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC)
-# define __lzo_forceinline __forceinline
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
-# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
-#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
-# define __lzo_forceinline __forceinline
-#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
-# define __lzo_forceinline __inline__ __attribute__((__always_inline__))
+# define __LZO_ASM_CLOBBER "cc", "memory"
+# define __LZO_ASM_CLOBBER_LIST_CC : "cc"
+# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "cc", "memory"
+# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/
#endif
#endif
-#if defined(__lzo_forceinline)
-# define __lzo_HAVE_forceinline 1
-#else
-# define __lzo_forceinline /*empty*/
-#endif
-#if !defined(__lzo_noinline)
-#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul)
-# define __lzo_noinline __attribute__((__noinline__,__used__))
-#elif (LZO_CC_GNUC >= 0x030200ul)
-# define __lzo_noinline __attribute__((__noinline__))
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_MSC)
-# define __lzo_noinline __declspec(noinline)
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800) && LZO_CC_SYNTAX_GNUC)
-# define __lzo_noinline __attribute__((__noinline__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_noinline __attribute__((__noinline__))
-#elif (LZO_CC_MSC && (_MSC_VER >= 1300))
-# define __lzo_noinline __declspec(noinline)
-#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64))
-# if defined(__cplusplus)
-# else
-# define __lzo_noinline __declspec(noinline)
+#if (LZO_ARCH_ALPHA)
+# define LZO_OPT_AVOID_UINT_INDEX 1
+#elif (LZO_ARCH_AMD64)
+# define LZO_OPT_AVOID_INT_INDEX 1
+# define LZO_OPT_AVOID_UINT_INDEX 1
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
# endif
-#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC >= 0x5100))
-# define __lzo_noinline __attribute__((__noinline__))
-#endif
-#endif
-#if defined(__lzo_noinline)
-# define __lzo_HAVE_noinline 1
-#else
-# define __lzo_noinline /*empty*/
-#endif
-#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline)
-# error "this should not happen"
-#endif
-#if !defined(__lzo_noreturn)
-#if (LZO_CC_GNUC >= 0x020700ul)
-# define __lzo_noreturn __attribute__((__noreturn__))
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC)
-# define __lzo_noreturn __declspec(noreturn)
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
-# define __lzo_noreturn __attribute__((__noreturn__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_noreturn __attribute__((__noreturn__))
-#elif (LZO_CC_MSC && (_MSC_VER >= 1200))
-# define __lzo_noreturn __declspec(noreturn)
-#endif
-#endif
-#if defined(__lzo_noreturn)
-# define __lzo_HAVE_noreturn 1
-#else
-# define __lzo_noreturn /*empty*/
-#endif
-#if !defined(__lzo_nothrow)
-#if (LZO_CC_GNUC >= 0x030300ul)
-# define __lzo_nothrow __attribute__((__nothrow__))
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 450) && LZO_CC_SYNTAX_MSC) && defined(__cplusplus)
-# define __lzo_nothrow __declspec(nothrow)
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 900) && LZO_CC_SYNTAX_GNUC)
-# define __lzo_nothrow __attribute__((__nothrow__))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_nothrow __attribute__((__nothrow__))
-#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus)
-# define __lzo_nothrow __declspec(nothrow)
-#endif
-#endif
-#if defined(__lzo_nothrow)
-# define __lzo_HAVE_nothrow 1
-#else
-# define __lzo_nothrow /*empty*/
-#endif
-#if !defined(__lzo_restrict)
-#if (LZO_CC_GNUC >= 0x030400ul)
-# define __lzo_restrict __restrict__
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 600) && LZO_CC_SYNTAX_GNUC)
-# define __lzo_restrict __restrict__
-#elif (LZO_CC_CLANG || LZO_CC_LLVM)
-# define __lzo_restrict __restrict__
-#elif (LZO_CC_MSC && (_MSC_VER >= 1400))
-# define __lzo_restrict __restrict
-#endif
-#endif
-#if defined(__lzo_restrict)
-# define __lzo_HAVE_restrict 1
-#else
-# define __lzo_restrict /*empty*/
-#endif
-#if !defined(__lzo_likely) && !defined(__lzo_unlikely)
-#if (LZO_CC_GNUC >= 0x030200ul)
-# define __lzo_likely(e) (__builtin_expect(!!(e),1))
-# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
-#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800))
-# define __lzo_likely(e) (__builtin_expect(!!(e),1))
-# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
-#elif (LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define __lzo_likely(e) (__builtin_expect(!!(e),1))
-# define __lzo_unlikely(e) (__builtin_expect(!!(e),0))
-#endif
-#endif
-#if defined(__lzo_likely)
-# define __lzo_HAVE_likely 1
-#else
-# define __lzo_likely(e) (e)
-#endif
-#if defined(__lzo_unlikely)
-# define __lzo_HAVE_unlikely 1
-#else
-# define __lzo_unlikely(e) (e)
-#endif
-#if !defined(LZO_UNUSED)
-# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
-# define LZO_UNUSED(var) ((void) &var)
-# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC)
-# define LZO_UNUSED(var) if (&var) ; else
-# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define LZO_UNUSED(var) ((void) var)
-# elif (LZO_CC_MSC && (_MSC_VER < 900))
-# define LZO_UNUSED(var) if (&var) ; else
-# elif (LZO_CC_KEILC)
-# define LZO_UNUSED(var) {extern int __lzo_unused[1-2*!(sizeof(var)>0)];}
-# elif (LZO_CC_PACIFICC)
-# define LZO_UNUSED(var) ((void) sizeof(var))
-# elif (LZO_CC_WATCOMC) && defined(__cplusplus)
-# define LZO_UNUSED(var) ((void) var)
-# else
-# define LZO_UNUSED(var) ((void) &var)
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
# endif
-#endif
-#if !defined(LZO_UNUSED_FUNC)
-# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600))
-# define LZO_UNUSED_FUNC(func) ((void) func)
-# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC)
-# define LZO_UNUSED_FUNC(func) if (func) ; else
-# elif (LZO_CC_CLANG || LZO_CC_LLVM)
-# define LZO_UNUSED_FUNC(func) ((void) &func)
-# elif (LZO_CC_MSC && (_MSC_VER < 900))
-# define LZO_UNUSED_FUNC(func) if (func) ; else
-# elif (LZO_CC_MSC)
-# define LZO_UNUSED_FUNC(func) ((void) &func)
-# elif (LZO_CC_KEILC || LZO_CC_PELLESC)
-# define LZO_UNUSED_FUNC(func) {extern int __lzo_unused[1-2*!(sizeof((int)func)>0)];}
-# else
-# define LZO_UNUSED_FUNC(func) ((void) func)
+# ifndef LZO_OPT_UNALIGNED64
+# define LZO_OPT_UNALIGNED64 1
# endif
-#endif
-#if !defined(LZO_UNUSED_LABEL)
-# if (LZO_CC_WATCOMC) && defined(__cplusplus)
-# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
-# elif (LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC)
-# define LZO_UNUSED_LABEL(l) if (0) goto l
-# else
-# define LZO_UNUSED_LABEL(l) switch(0) case 1:goto l
+#elif (LZO_ARCH_ARM)
+# if defined(__ARM_FEATURE_UNALIGNED)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
+# elif defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM+0) >= 7)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
+# elif defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM+0) >= 6) && !defined(__TARGET_PROFILE_M)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
# endif
-#endif
-#if !defined(LZO_DEFINE_UNINITIALIZED_VAR)
-# if 0
-# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var
-# elif 0 && (LZO_CC_GNUC)
-# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var
-# else
-# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init
+#elif (LZO_ARCH_ARM64)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
# endif
-#endif
-#if !defined(LZO_UNCONST_CAST)
-# if 0 && defined(__cplusplus)
-# define LZO_UNCONST_CAST(t,e) (const_cast<t> (e))
-# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE)
-# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((lzo_uintptr_t) ((const void *) (e))))))
-# else
-# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((char *) ((const void *) (e)))))
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
# endif
-#endif
-#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER)
-# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC)
-# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)];
-# elif (LZO_CC_DMC || LZO_CC_SYMANTECC)
-# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1u-2*!(e)];
-# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
-# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-!(e)];
-# else
-# define LZO_COMPILE_TIME_ASSERT_HEADER(e) extern int __lzo_cta[1-2*!(e)];
+# ifndef LZO_OPT_UNALIGNED64
+# define LZO_OPT_UNALIGNED64 1
# endif
-#endif
-#if !defined(LZO_COMPILE_TIME_ASSERT)
-# if (LZO_CC_AZTECC)
-# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-!(e)];}
-# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
-# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
-# elif (LZO_CC_MSC && (_MSC_VER < 900))
-# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
-# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295))
-# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break;
-# else
-# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __lzo_cta_t[1-2*!(e)];}
+#elif (LZO_ARCH_CRIS)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
# endif
-#endif
-#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64)
-# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC)
-# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC)
-# define __lzo_cdecl __cdecl
-# define __lzo_cdecl_atexit /*empty*/
-# define __lzo_cdecl_main __cdecl
-# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
-# define __lzo_cdecl_qsort __pascal
-# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
-# define __lzo_cdecl_qsort _stdcall
-# else
-# define __lzo_cdecl_qsort __cdecl
-# endif
-# elif (LZO_CC_WATCOMC)
-# define __lzo_cdecl __cdecl
-# else
-# define __lzo_cdecl __cdecl
-# define __lzo_cdecl_atexit __cdecl
-# define __lzo_cdecl_main __cdecl
-# define __lzo_cdecl_qsort __cdecl
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
# endif
-# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC)
-# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC))
-# define __lzo_cdecl_sighandler __pascal
-# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC))
-# define __lzo_cdecl_sighandler _stdcall
-# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE)
-# define __lzo_cdecl_sighandler __clrcall
-# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700))
-# if defined(_DLL)
-# define __lzo_cdecl_sighandler _far _cdecl _loadds
-# elif defined(_MT)
-# define __lzo_cdecl_sighandler _far _cdecl
-# else
-# define __lzo_cdecl_sighandler _cdecl
-# endif
-# else
-# define __lzo_cdecl_sighandler __cdecl
+#elif (LZO_ARCH_I386)
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
# endif
-#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC)
-# define __lzo_cdecl __cdecl
-#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC))
-# define __lzo_cdecl cdecl
-#endif
-#if !defined(__lzo_cdecl)
-# define __lzo_cdecl /*empty*/
-#endif
-#if !defined(__lzo_cdecl_atexit)
-# define __lzo_cdecl_atexit /*empty*/
-#endif
-#if !defined(__lzo_cdecl_main)
-# define __lzo_cdecl_main /*empty*/
-#endif
-#if !defined(__lzo_cdecl_qsort)
-# define __lzo_cdecl_qsort /*empty*/
-#endif
-#if !defined(__lzo_cdecl_sighandler)
-# define __lzo_cdecl_sighandler /*empty*/
-#endif
-#if !defined(__lzo_cdecl_va)
-# define __lzo_cdecl_va __lzo_cdecl
-#endif
-#if !(LZO_CFG_NO_WINDOWS_H)
-#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64)
-# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000))
-# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__)
-# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul)))
-# else
-# define LZO_HAVE_WINDOWS_H 1
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
# endif
-#endif
-#endif
-#if (LZO_ARCH_ALPHA)
-# define LZO_OPT_AVOID_UINT_INDEX 1
-# define LZO_OPT_AVOID_SHORT 1
-# define LZO_OPT_AVOID_USHORT 1
-#elif (LZO_ARCH_AMD64)
-# define LZO_OPT_AVOID_INT_INDEX 1
-# define LZO_OPT_AVOID_UINT_INDEX 1
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
-# define LZO_OPT_UNALIGNED64 1
-#elif (LZO_ARCH_ARM && LZO_ARCH_ARM_THUMB)
-#elif (LZO_ARCH_ARM)
-# define LZO_OPT_AVOID_SHORT 1
-# define LZO_OPT_AVOID_USHORT 1
-#elif (LZO_ARCH_CRIS)
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
-#elif (LZO_ARCH_I386)
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
#elif (LZO_ARCH_IA64)
-# define LZO_OPT_AVOID_INT_INDEX 1
-# define LZO_OPT_AVOID_UINT_INDEX 1
-# define LZO_OPT_PREFER_POSTINC 1
+# define LZO_OPT_AVOID_INT_INDEX 1
+# define LZO_OPT_AVOID_UINT_INDEX 1
+# define LZO_OPT_PREFER_POSTINC 1
#elif (LZO_ARCH_M68K)
-# define LZO_OPT_PREFER_POSTINC 1
-# define LZO_OPT_PREFER_PREDEC 1
+# define LZO_OPT_PREFER_POSTINC 1
+# define LZO_OPT_PREFER_PREDEC 1
# if defined(__mc68020__) && !defined(__mcoldfire__)
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
# endif
#elif (LZO_ARCH_MIPS)
-# define LZO_OPT_AVOID_UINT_INDEX 1
+# define LZO_OPT_AVOID_UINT_INDEX 1
#elif (LZO_ARCH_POWERPC)
-# define LZO_OPT_PREFER_PREINC 1
-# define LZO_OPT_PREFER_PREDEC 1
+# define LZO_OPT_PREFER_PREINC 1
+# define LZO_OPT_PREFER_PREDEC 1
# if (LZO_ABI_BIG_ENDIAN)
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
+# if (LZO_WORDSIZE == 8)
+# ifndef LZO_OPT_UNALIGNED64
+# define LZO_OPT_UNALIGNED64 1
+# endif
+# endif
# endif
#elif (LZO_ARCH_S390)
-# define LZO_OPT_UNALIGNED16 1
-# define LZO_OPT_UNALIGNED32 1
-# if (LZO_SIZEOF_SIZE_T == 8)
-# define LZO_OPT_UNALIGNED64 1
+# ifndef LZO_OPT_UNALIGNED16
+# define LZO_OPT_UNALIGNED16 1
+# endif
+# ifndef LZO_OPT_UNALIGNED32
+# define LZO_OPT_UNALIGNED32 1
+# endif
+# if (LZO_WORDSIZE == 8)
+# ifndef LZO_OPT_UNALIGNED64
+# define LZO_OPT_UNALIGNED64 1
+# endif
# endif
#elif (LZO_ARCH_SH)
-# define LZO_OPT_PREFER_POSTINC 1
-# define LZO_OPT_PREFER_PREDEC 1
+# define LZO_OPT_PREFER_POSTINC 1
+# define LZO_OPT_PREFER_PREDEC 1
#endif
#ifndef LZO_CFG_NO_INLINE_ASM
-#if (LZO_CC_LLVM)
+#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC)
+# define LZO_CFG_NO_INLINE_ASM 1
+#elif (LZO_CC_LLVM)
# define LZO_CFG_NO_INLINE_ASM 1
#endif
#endif
+#if (LZO_CFG_NO_INLINE_ASM)
+# undef LZO_ASM_SYNTAX_MSC
+# undef LZO_ASM_SYNTAX_GNUC
+# undef __LZO_ASM_CLOBBER
+# undef __LZO_ASM_CLOBBER_LIST_CC
+# undef __LZO_ASM_CLOBBER_LIST_CC_MEMORY
+# undef __LZO_ASM_CLOBBER_LIST_EMPTY
+#endif
#ifndef LZO_CFG_NO_UNALIGNED
#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC)
# define LZO_CFG_NO_UNALIGNED 1
@@ -1804,25 +2594,6 @@ extern "C" {
# undef LZO_OPT_UNALIGNED32
# undef LZO_OPT_UNALIGNED64
#endif
-#if (LZO_CFG_NO_INLINE_ASM)
-#elif (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
-# define LZO_ASM_SYNTAX_MSC 1
-#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC))
-#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul))
-#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
-# define LZO_ASM_SYNTAX_GNUC 1
-#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE))
-# define LZO_ASM_SYNTAX_GNUC 1
-#endif
-#if (LZO_ASM_SYNTAX_GNUC)
-#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul))
-# define __LZO_ASM_CLOBBER "ax"
-#elif (LZO_CC_INTELC)
-# define __LZO_ASM_CLOBBER "memory"
-#else
-# define __LZO_ASM_CLOBBER "cc", "memory"
-#endif
-#endif
#if defined(__LZO_INFOSTR_MM)
#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM))
# define __LZO_INFOSTR_MM ""
@@ -1866,6 +2637,381 @@ extern "C" {
#define LZO_INFO_STRING \
LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \
" " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER
+#if !(LZO_CFG_SKIP_LZO_TYPES)
+#if (!(LZO_SIZEOF_SHORT+0 > 0 && LZO_SIZEOF_INT+0 > 0 && LZO_SIZEOF_LONG+0 > 0))
+# error "missing defines for sizes"
+#endif
+#if (!(LZO_SIZEOF_PTRDIFF_T+0 > 0 && LZO_SIZEOF_SIZE_T+0 > 0 && LZO_SIZEOF_VOID_P+0 > 0))
+# error "missing defines for sizes"
+#endif
+#if !defined(lzo_llong_t)
+#if (LZO_SIZEOF_LONG_LONG+0 > 0)
+__lzo_gnuc_extension__ typedef long long lzo_llong_t__;
+__lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__;
+# define lzo_llong_t lzo_llong_t__
+# define lzo_ullong_t lzo_ullong_t__
+#endif
+#endif
+#if !defined(lzo_int16e_t)
+#if (LZO_SIZEOF_LONG == 2)
+# define lzo_int16e_t long
+# define lzo_uint16e_t unsigned long
+#elif (LZO_SIZEOF_INT == 2)
+# define lzo_int16e_t int
+# define lzo_uint16e_t unsigned int
+#elif (LZO_SIZEOF_SHORT == 2)
+# define lzo_int16e_t short int
+# define lzo_uint16e_t unsigned short int
+#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM)
+ typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__)));
+ typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__)));
+# define lzo_int16e_t lzo_int16e_hi_t__
+# define lzo_uint16e_t lzo_uint16e_hi_t__
+#elif (LZO_SIZEOF___INT16 == 2)
+# define lzo_int16e_t __int16
+# define lzo_uint16e_t unsigned __int16
+#else
+#endif
+#endif
+#if defined(lzo_int16e_t)
+# define LZO_SIZEOF_LZO_INT16E_T 2
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == 2)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == LZO_SIZEOF_LZO_INT16E_T)
+#endif
+#if !defined(lzo_int32e_t)
+#if (LZO_SIZEOF_LONG == 4)
+# define lzo_int32e_t long int
+# define lzo_uint32e_t unsigned long int
+#elif (LZO_SIZEOF_INT == 4)
+# define lzo_int32e_t int
+# define lzo_uint32e_t unsigned int
+#elif (LZO_SIZEOF_SHORT == 4)
+# define lzo_int32e_t short int
+# define lzo_uint32e_t unsigned short int
+#elif (LZO_SIZEOF_LONG_LONG == 4)
+# define lzo_int32e_t lzo_llong_t
+# define lzo_uint32e_t lzo_ullong_t
+#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L)
+ typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__)));
+ typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__)));
+# define lzo_int32e_t lzo_int32e_si_t__
+# define lzo_uint32e_t lzo_uint32e_si_t__
+#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L)
+ typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__)));
+ typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__)));
+# define lzo_int32e_t lzo_int32e_si_t__
+# define lzo_uint32e_t lzo_uint32e_si_t__
+# define LZO_INT32_C(c) (c##LL)
+# define LZO_UINT32_C(c) (c##ULL)
+#elif (LZO_SIZEOF___INT32 == 4)
+# define lzo_int32e_t __int32
+# define lzo_uint32e_t unsigned __int32
+#else
+#endif
+#endif
+#if defined(lzo_int32e_t)
+# define LZO_SIZEOF_LZO_INT32E_T 4
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == 4)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == LZO_SIZEOF_LZO_INT32E_T)
+#endif
+#if !defined(lzo_int64e_t)
+#if (LZO_SIZEOF___INT64 == 8)
+# if (LZO_CC_BORLANDC) && !(LZO_CFG_TYPE_PREFER___INT64)
+# define LZO_CFG_TYPE_PREFER___INT64 1
+# endif
+#endif
+#if (LZO_SIZEOF_INT == 8) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG)
+# define lzo_int64e_t int
+# define lzo_uint64e_t unsigned int
+# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_INT
+#elif (LZO_SIZEOF_LONG == 8)
+# define lzo_int64e_t long int
+# define lzo_uint64e_t unsigned long int
+# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG
+#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_TYPE_PREFER___INT64)
+# define lzo_int64e_t lzo_llong_t
+# define lzo_uint64e_t lzo_ullong_t
+# if (LZO_CC_BORLANDC)
+# define LZO_INT64_C(c) ((c) + 0ll)
+# define LZO_UINT64_C(c) ((c) + 0ull)
+# elif 0
+# define LZO_INT64_C(c) (__lzo_gnuc_extension__ (c##LL))
+# define LZO_UINT64_C(c) (__lzo_gnuc_extension__ (c##ULL))
+# else
+# define LZO_INT64_C(c) (c##LL)
+# define LZO_UINT64_C(c) (c##ULL)
+# endif
+# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG_LONG
+#elif (LZO_SIZEOF___INT64 == 8)
+# define lzo_int64e_t __int64
+# define lzo_uint64e_t unsigned __int64
+# if (LZO_CC_BORLANDC)
+# define LZO_INT64_C(c) ((c) + 0i64)
+# define LZO_UINT64_C(c) ((c) + 0ui64)
+# else
+# define LZO_INT64_C(c) (c##i64)
+# define LZO_UINT64_C(c) (c##ui64)
+# endif
+# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF___INT64
+#else
+#endif
+#endif
+#if defined(lzo_int64e_t)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == 8)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == LZO_SIZEOF_LZO_INT64E_T)
+#endif
+#if !defined(lzo_int32l_t)
+#if defined(lzo_int32e_t)
+# define lzo_int32l_t lzo_int32e_t
+# define lzo_uint32l_t lzo_uint32e_t
+# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LZO_INT32E_T
+#elif (LZO_SIZEOF_INT >= 4) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG)
+# define lzo_int32l_t int
+# define lzo_uint32l_t unsigned int
+# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_INT
+#elif (LZO_SIZEOF_LONG >= 4)
+# define lzo_int32l_t long int
+# define lzo_uint32l_t unsigned long int
+# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LONG
+#else
+# error "lzo_int32l_t"
+#endif
+#endif
+#if 1
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) >= 4)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) == LZO_SIZEOF_LZO_INT32L_T)
+#endif
+#if !defined(lzo_int64l_t)
+#if defined(lzo_int64e_t)
+# define lzo_int64l_t lzo_int64e_t
+# define lzo_uint64l_t lzo_uint64e_t
+# define LZO_SIZEOF_LZO_INT64L_T LZO_SIZEOF_LZO_INT64E_T
+#else
+#endif
+#endif
+#if defined(lzo_int64l_t)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) >= 8)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) == LZO_SIZEOF_LZO_INT64L_T)
+#endif
+#if !defined(lzo_int32f_t)
+#if (LZO_SIZEOF_SIZE_T >= 8)
+# define lzo_int32f_t lzo_int64l_t
+# define lzo_uint32f_t lzo_uint64l_t
+# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT64L_T
+#else
+# define lzo_int32f_t lzo_int32l_t
+# define lzo_uint32f_t lzo_uint32l_t
+# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT32L_T
+#endif
+#endif
+#if 1
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) >= 4)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) == LZO_SIZEOF_LZO_INT32F_T)
+#endif
+#if !defined(lzo_int64f_t)
+#if defined(lzo_int64l_t)
+# define lzo_int64f_t lzo_int64l_t
+# define lzo_uint64f_t lzo_uint64l_t
+# define LZO_SIZEOF_LZO_INT64F_T LZO_SIZEOF_LZO_INT64L_T
+#else
+#endif
+#endif
+#if defined(lzo_int64f_t)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) >= 8)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) == LZO_SIZEOF_LZO_INT64F_T)
+#endif
+#if !defined(lzo_intptr_t)
+#if 1 && (LZO_OS_OS400 && (LZO_SIZEOF_VOID_P == 16))
+# define __LZO_INTPTR_T_IS_POINTER 1
+ typedef char* lzo_intptr_t;
+ typedef char* lzo_uintptr_t;
+# define lzo_intptr_t lzo_intptr_t
+# define lzo_uintptr_t lzo_uintptr_t
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P
+#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4))
+ typedef __w64 int lzo_intptr_t;
+ typedef __w64 unsigned int lzo_uintptr_t;
+# define lzo_intptr_t lzo_intptr_t
+# define lzo_uintptr_t lzo_uintptr_t
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT
+#elif (LZO_SIZEOF_SHORT == LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT > LZO_SIZEOF_VOID_P)
+# define lzo_intptr_t short
+# define lzo_uintptr_t unsigned short
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_SHORT
+#elif (LZO_SIZEOF_INT >= LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG)
+# define lzo_intptr_t int
+# define lzo_uintptr_t unsigned int
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT
+#elif (LZO_SIZEOF_LONG >= LZO_SIZEOF_VOID_P)
+# define lzo_intptr_t long
+# define lzo_uintptr_t unsigned long
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LONG
+#elif (LZO_SIZEOF_LZO_INT64L_T >= LZO_SIZEOF_VOID_P)
+# define lzo_intptr_t lzo_int64l_t
+# define lzo_uintptr_t lzo_uint64l_t
+# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LZO_INT64L_T
+#else
+# error "lzo_intptr_t"
+#endif
+#endif
+#if 1
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) >= sizeof(void *))
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) == sizeof(lzo_uintptr_t))
+#endif
+#if !defined(lzo_word_t)
+#if defined(LZO_WORDSIZE) && (LZO_WORDSIZE+0 > 0)
+#if (LZO_WORDSIZE == LZO_SIZEOF_LZO_INTPTR_T) && !(__LZO_INTPTR_T_IS_POINTER)
+# define lzo_word_t lzo_uintptr_t
+# define lzo_sword_t lzo_intptr_t
+# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INTPTR_T
+#elif (LZO_WORDSIZE == LZO_SIZEOF_LONG)
+# define lzo_word_t unsigned long
+# define lzo_sword_t long
+# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LONG
+#elif (LZO_WORDSIZE == LZO_SIZEOF_INT)
+# define lzo_word_t unsigned int
+# define lzo_sword_t int
+# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_INT
+#elif (LZO_WORDSIZE == LZO_SIZEOF_SHORT)
+# define lzo_word_t unsigned short
+# define lzo_sword_t short
+# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_SHORT
+#elif (LZO_WORDSIZE == 1)
+# define lzo_word_t unsigned char
+# define lzo_sword_t signed char
+# define LZO_SIZEOF_LZO_WORD_T 1
+#elif (LZO_WORDSIZE == LZO_SIZEOF_LZO_INT64L_T)
+# define lzo_word_t lzo_uint64l_t
+# define lzo_sword_t lzo_int64l_t
+# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T
+#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC)
+#if 0
+ typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__)));
+ typedef int lzo_sword_t __attribute__((__mode__(__V16QI__)));
+# define lzo_word_t lzo_word_t
+# define lzo_sword_t lzo_sword_t
+# define LZO_SIZEOF_LZO_WORD_T 16
+#endif
+#else
+# error "lzo_word_t"
+#endif
+#endif
+#endif
+#if 1 && defined(lzo_word_t)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_word_t) == LZO_WORDSIZE)
+ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_sword_t) == LZO_WORDSIZE)
+#endif
+#if 1
+#define lzo_int8_t signed char
+#define lzo_uint8_t unsigned char
+#define LZO_SIZEOF_LZO_INT8_T 1
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == sizeof(lzo_uint8_t))
+#endif
+#if defined(lzo_int16e_t)
+#define lzo_int16_t lzo_int16e_t
+#define lzo_uint16_t lzo_uint16e_t
+#define LZO_SIZEOF_LZO_INT16_T LZO_SIZEOF_LZO_INT16E_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == sizeof(lzo_uint16_t))
+#endif
+#if defined(lzo_int32e_t)
+#define lzo_int32_t lzo_int32e_t
+#define lzo_uint32_t lzo_uint32e_t
+#define LZO_SIZEOF_LZO_INT32_T LZO_SIZEOF_LZO_INT32E_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == sizeof(lzo_uint32_t))
+#endif
+#if defined(lzo_int64e_t)
+#define lzo_int64_t lzo_int64e_t
+#define lzo_uint64_t lzo_uint64e_t
+#define LZO_SIZEOF_LZO_INT64_T LZO_SIZEOF_LZO_INT64E_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == sizeof(lzo_uint64_t))
+#endif
+#if 1
+#define lzo_int_least32_t lzo_int32l_t
+#define lzo_uint_least32_t lzo_uint32l_t
+#define LZO_SIZEOF_LZO_INT_LEAST32_T LZO_SIZEOF_LZO_INT32L_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) >= 4)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) == sizeof(lzo_uint_least32_t))
+#endif
+#if defined(lzo_int64l_t)
+#define lzo_int_least64_t lzo_int64l_t
+#define lzo_uint_least64_t lzo_uint64l_t
+#define LZO_SIZEOF_LZO_INT_LEAST64_T LZO_SIZEOF_LZO_INT64L_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) >= 8)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) == sizeof(lzo_uint_least64_t))
+#endif
+#if 1
+#define lzo_int_fast32_t lzo_int32f_t
+#define lzo_uint_fast32_t lzo_uint32f_t
+#define LZO_SIZEOF_LZO_INT_FAST32_T LZO_SIZEOF_LZO_INT32F_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) >= 4)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) == sizeof(lzo_uint_fast32_t))
+#endif
+#if defined(lzo_int64f_t)
+#define lzo_int_fast64_t lzo_int64f_t
+#define lzo_uint_fast64_t lzo_uint64f_t
+#define LZO_SIZEOF_LZO_INT_FAST64_T LZO_SIZEOF_LZO_INT64F_T
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) >= 8)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) == sizeof(lzo_uint_fast64_t))
+#endif
+#if !defined(LZO_INT16_C)
+# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 2)
+# define LZO_INT16_C(c) ((c) + 0)
+# define LZO_UINT16_C(c) ((c) + 0U)
+# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 2)
+# define LZO_INT16_C(c) ((c) + 0L)
+# define LZO_UINT16_C(c) ((c) + 0UL)
+# elif (LZO_SIZEOF_INT >= 2)
+# define LZO_INT16_C(c) (c)
+# define LZO_UINT16_C(c) (c##U)
+# elif (LZO_SIZEOF_LONG >= 2)
+# define LZO_INT16_C(c) (c##L)
+# define LZO_UINT16_C(c) (c##UL)
+# else
+# error "LZO_INT16_C"
+# endif
+#endif
+#if !defined(LZO_INT32_C)
+# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 4)
+# define LZO_INT32_C(c) ((c) + 0)
+# define LZO_UINT32_C(c) ((c) + 0U)
+# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 4)
+# define LZO_INT32_C(c) ((c) + 0L)
+# define LZO_UINT32_C(c) ((c) + 0UL)
+# elif (LZO_SIZEOF_INT >= 4)
+# define LZO_INT32_C(c) (c)
+# define LZO_UINT32_C(c) (c##U)
+# elif (LZO_SIZEOF_LONG >= 4)
+# define LZO_INT32_C(c) (c##L)
+# define LZO_UINT32_C(c) (c##UL)
+# elif (LZO_SIZEOF_LONG_LONG >= 4)
+# define LZO_INT32_C(c) (c##LL)
+# define LZO_UINT32_C(c) (c##ULL)
+# else
+# error "LZO_INT32_C"
+# endif
+#endif
+#if !defined(LZO_INT64_C) && defined(lzo_int64l_t)
+# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 8)
+# define LZO_INT64_C(c) ((c) + 0)
+# define LZO_UINT64_C(c) ((c) + 0U)
+# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 8)
+# define LZO_INT64_C(c) ((c) + 0L)
+# define LZO_UINT64_C(c) ((c) + 0UL)
+# elif (LZO_SIZEOF_INT >= 8)
+# define LZO_INT64_C(c) (c)
+# define LZO_UINT64_C(c) (c##U)
+# elif (LZO_SIZEOF_LONG >= 8)
+# define LZO_INT64_C(c) (c##L)
+# define LZO_UINT64_C(c) (c##UL)
+# else
+# error "LZO_INT64_C"
+# endif
+#endif
+#endif
#endif
@@ -1874,7 +3020,7 @@ extern "C" {
#undef LZO_HAVE_CONFIG_H
#include "minilzo.h"
-#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2060)
+#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2080)
# error "version mismatch in miniLZO source files"
#endif
@@ -1886,23 +3032,9 @@ extern "C" {
#define __LZO_CONF_H 1
#if !defined(__LZO_IN_MINILZO)
-#if (LZO_CFG_FREESTANDING)
+#if defined(LZO_CFG_FREESTANDING) && (LZO_CFG_FREESTANDING)
# define LZO_LIBC_FREESTANDING 1
# define LZO_OS_FREESTANDING 1
-# define ACC_LIBC_FREESTANDING 1
-# define ACC_OS_FREESTANDING 1
-#endif
-#if (LZO_CFG_NO_UNALIGNED)
-# define ACC_CFG_NO_UNALIGNED 1
-#endif
-#if (LZO_ARCH_GENERIC)
-# define ACC_ARCH_GENERIC 1
-#endif
-#if (LZO_ABI_NEUTRAL_ENDIAN)
-# define ACC_ABI_NEUTRAL_ENDIAN 1
-#endif
-#if (LZO_HAVE_CONFIG_H)
-# define ACC_CONFIG_NO_HEADER 1
#endif
#if defined(LZO_CFG_EXTRA_CONFIG_HEADER)
# include LZO_CFG_EXTRA_CONFIG_HEADER
@@ -1911,22 +3043,27 @@ extern "C" {
# error "include this file first"
#endif
#include "lzo/lzoconf.h"
+#if defined(LZO_CFG_EXTRA_CONFIG_HEADER2)
+# include LZO_CFG_EXTRA_CONFIG_HEADER2
+#endif
#endif
-#if (LZO_VERSION < 0x02000) || !defined(__LZOCONF_H_INCLUDED)
+#if (LZO_VERSION < 0x2080) || !defined(__LZOCONF_H_INCLUDED)
# error "version mismatch"
#endif
-#if (LZO_CC_BORLANDC && LZO_ARCH_I086)
-# pragma option -h
+#if (LZO_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1100))
+# pragma warning(disable: 4702)
#endif
-
#if (LZO_CC_MSC && (_MSC_VER >= 1000))
# pragma warning(disable: 4127 4701)
+# pragma warning(disable: 4514 4710 4711)
#endif
#if (LZO_CC_MSC && (_MSC_VER >= 1300))
# pragma warning(disable: 4820)
-# pragma warning(disable: 4514 4710 4711)
+#endif
+#if (LZO_CC_MSC && (_MSC_VER >= 1800))
+# pragma warning(disable: 4746)
#endif
#if (LZO_CC_SUNPROC)
@@ -1937,48 +3074,15 @@ extern "C" {
#endif
#endif
-#if (__LZO_MMODEL_HUGE) && !(LZO_HAVE_MM_HUGE_PTR)
-# error "this should not happen - check defines for __huge"
-#endif
-
-#if defined(__LZO_IN_MINILZO) || defined(LZO_CFG_FREESTANDING)
-#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16)
-# define ACC_WANT_ACC_INCD_H 1
-# define ACC_WANT_ACC_INCE_H 1
-# define ACC_WANT_ACC_INCI_H 1
+#if defined(__LZO_IN_MINILZO) || (LZO_CFG_FREESTANDING)
#elif 1
# include <string.h>
#else
-# define ACC_WANT_ACC_INCD_H 1
+# define LZO_WANT_ACC_INCD_H 1
#endif
-
-#if (LZO_ARCH_I086)
-# define ACC_MM_AHSHIFT LZO_MM_AHSHIFT
-# define ACC_PTR_FP_OFF(x) (((const unsigned __far*)&(x))[0])
-# define ACC_PTR_FP_SEG(x) (((const unsigned __far*)&(x))[1])
-# define ACC_PTR_MK_FP(s,o) ((void __far*)(((unsigned long)(s)<<16)+(unsigned)(o)))
-#endif
-
-#if !defined(lzo_uintptr_t)
-# if defined(__LZO_MMODEL_HUGE)
-# define lzo_uintptr_t unsigned long
-# elif 1 && defined(LZO_OS_OS400) && (LZO_SIZEOF_VOID_P == 16)
-# define __LZO_UINTPTR_T_IS_POINTER 1
- typedef char* lzo_uintptr_t;
-# define lzo_uintptr_t lzo_uintptr_t
-# elif (LZO_SIZEOF_SIZE_T == LZO_SIZEOF_VOID_P)
-# define lzo_uintptr_t size_t
-# elif (LZO_SIZEOF_LONG == LZO_SIZEOF_VOID_P)
-# define lzo_uintptr_t unsigned long
-# elif (LZO_SIZEOF_INT == LZO_SIZEOF_VOID_P)
-# define lzo_uintptr_t unsigned int
-# elif (LZO_SIZEOF_LONG_LONG == LZO_SIZEOF_VOID_P)
-# define lzo_uintptr_t unsigned long long
-# else
-# define lzo_uintptr_t size_t
-# endif
+#if defined(LZO_HAVE_CONFIG_H)
+# define LZO_CFG_NO_CONFIG_HEADER 1
#endif
-LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
#if 1 && !defined(LZO_CFG_FREESTANDING)
#if 1 && !defined(HAVE_STRING_H)
@@ -2002,6 +3106,23 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
#include <string.h>
#endif
+#if 1 || defined(lzo_int8_t) || defined(lzo_uint8_t)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint8_t) == 1)
+#endif
+#if 1 || defined(lzo_int16_t) || defined(lzo_uint16_t)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint16_t) == 2)
+#endif
+#if 1 || defined(lzo_int32_t) || defined(lzo_uint32_t)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32_t) == 4)
+#endif
+#if defined(lzo_int64_t) || defined(lzo_uint64_t)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64_t) == 8)
+#endif
+
#if (LZO_CFG_FREESTANDING)
# undef HAVE_MEMCMP
# undef HAVE_MEMCPY
@@ -2012,28 +3133,28 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
#if !(HAVE_MEMCMP)
# undef memcmp
# define memcmp(a,b,c) lzo_memcmp(a,b,c)
-#elif !(__LZO_MMODEL_HUGE)
+#else
# undef lzo_memcmp
# define lzo_memcmp(a,b,c) memcmp(a,b,c)
#endif
#if !(HAVE_MEMCPY)
# undef memcpy
# define memcpy(a,b,c) lzo_memcpy(a,b,c)
-#elif !(__LZO_MMODEL_HUGE)
+#else
# undef lzo_memcpy
# define lzo_memcpy(a,b,c) memcpy(a,b,c)
#endif
#if !(HAVE_MEMMOVE)
# undef memmove
# define memmove(a,b,c) lzo_memmove(a,b,c)
-#elif !(__LZO_MMODEL_HUGE)
+#else
# undef lzo_memmove
# define lzo_memmove(a,b,c) memmove(a,b,c)
#endif
#if !(HAVE_MEMSET)
# undef memset
# define memset(a,b,c) lzo_memset(a,b,c)
-#elif !(__LZO_MMODEL_HUGE)
+#else
# undef lzo_memset
# define lzo_memset(a,b,c) memset(a,b,c)
#endif
@@ -2058,27 +3179,29 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr)
#endif
-#if !defined(__lzo_inline)
-# define __lzo_inline /*empty*/
-#endif
-#if !defined(__lzo_forceinline)
-# define __lzo_forceinline /*empty*/
-#endif
-#if !defined(__lzo_noinline)
-# define __lzo_noinline /*empty*/
-#endif
-
#if (LZO_CFG_PGO)
-# undef __acc_likely
-# undef __acc_unlikely
# undef __lzo_likely
# undef __lzo_unlikely
-# define __acc_likely(e) (e)
-# define __acc_unlikely(e) (e)
# define __lzo_likely(e) (e)
# define __lzo_unlikely(e) (e)
#endif
+#undef _
+#undef __
+#undef ___
+#undef ____
+#undef _p0
+#undef _p1
+#undef _p2
+#undef _p3
+#undef _p4
+#undef _s0
+#undef _s1
+#undef _s2
+#undef _s3
+#undef _s4
+#undef _ww
+
#if 1
# define LZO_BYTE(x) ((unsigned char) (x))
#else
@@ -2097,84 +3220,548 @@ LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
#define LZO_SIZE(bits) (1u << (bits))
#define LZO_MASK(bits) (LZO_SIZE(bits) - 1)
-#define LZO_LSIZE(bits) (1ul << (bits))
-#define LZO_LMASK(bits) (LZO_LSIZE(bits) - 1)
-
#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits))
#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1)
#if !defined(DMUL)
#if 0
-# define DMUL(a,b) ((lzo_xint) ((lzo_uint32)(a) * (lzo_uint32)(b)))
+# define DMUL(a,b) ((lzo_xint) ((lzo_uint32_t)(a) * (lzo_uint32_t)(b)))
#else
# define DMUL(a,b) ((lzo_xint) ((a) * (b)))
#endif
#endif
-#if 1 && (LZO_ARCH_AMD64 || LZO_ARCH_I386 || LZO_ARCH_POWERPC)
-# if (LZO_SIZEOF_SHORT == 2)
-# define LZO_UNALIGNED_OK_2 1
-# endif
-# if (LZO_SIZEOF_INT == 4)
-# define LZO_UNALIGNED_OK_4 1
-# endif
+#ifndef __LZO_FUNC_H
+#define __LZO_FUNC_H 1
+
+#if !defined(LZO_BITOPS_USE_ASM_BITSCAN) && !defined(LZO_BITOPS_USE_GNUC_BITSCAN) && !defined(LZO_BITOPS_USE_MSC_BITSCAN)
+#if 1 && (LZO_ARCH_AMD64) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_ASM_SYNTAX_GNUC)
+#define LZO_BITOPS_USE_ASM_BITSCAN 1
+#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_LLVM && (!defined(__llvm_tools_version__) || (__llvm_tools_version__+0 >= 0x010500ul))))
+#define LZO_BITOPS_USE_GNUC_BITSCAN 1
+#elif (LZO_OS_WIN32 || LZO_OS_WIN64) && ((LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 1010)) || (LZO_CC_MSC && (_MSC_VER >= 1400)))
+#define LZO_BITOPS_USE_MSC_BITSCAN 1
+#if (LZO_CC_MSC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386)
+#include <intrin.h>
#endif
-#if 1 && (LZO_ARCH_AMD64)
-# if defined(LZO_UINT64_MAX)
-# define LZO_UNALIGNED_OK_8 1
-# endif
+#if (LZO_CC_MSC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386)
+#pragma intrinsic(_BitScanReverse)
+#pragma intrinsic(_BitScanForward)
#endif
-#if (LZO_CFG_NO_UNALIGNED)
-# undef LZO_UNALIGNED_OK_2
-# undef LZO_UNALIGNED_OK_4
-# undef LZO_UNALIGNED_OK_8
-#endif
-
-#undef UA_GET16
-#undef UA_SET16
-#undef UA_COPY16
-#undef UA_GET32
-#undef UA_SET32
-#undef UA_COPY32
-#undef UA_GET64
-#undef UA_SET64
-#undef UA_COPY64
-#if defined(LZO_UNALIGNED_OK_2)
- LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(unsigned short) == 2)
-# if 1 && defined(ACC_UA_COPY16)
-# define UA_GET16 ACC_UA_GET16
-# define UA_SET16 ACC_UA_SET16
-# define UA_COPY16 ACC_UA_COPY16
-# else
-# define UA_GET16(p) (* (__lzo_ua_volatile const lzo_ushortp) (__lzo_ua_volatile const lzo_voidp) (p))
-# define UA_SET16(p,v) ((* (__lzo_ua_volatile lzo_ushortp) (__lzo_ua_volatile lzo_voidp) (p)) = (unsigned short) (v))
-# define UA_COPY16(d,s) UA_SET16(d, UA_GET16(s))
-# endif
+#if (LZO_CC_MSC) && (LZO_ARCH_AMD64)
+#pragma intrinsic(_BitScanReverse64)
+#pragma intrinsic(_BitScanForward64)
#endif
-#if defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
- LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32) == 4)
-# if 1 && defined(ACC_UA_COPY32)
-# define UA_GET32 ACC_UA_GET32
-# define UA_SET32 ACC_UA_SET32
-# define UA_COPY32 ACC_UA_COPY32
-# else
-# define UA_GET32(p) (* (__lzo_ua_volatile const lzo_uint32p) (__lzo_ua_volatile const lzo_voidp) (p))
-# define UA_SET32(p,v) ((* (__lzo_ua_volatile lzo_uint32p) (__lzo_ua_volatile lzo_voidp) (p)) = (lzo_uint32) (v))
-# define UA_COPY32(d,s) UA_SET32(d, UA_GET32(s))
-# endif
#endif
-#if defined(LZO_UNALIGNED_OK_8)
- LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64) == 8)
-# if 1 && defined(ACC_UA_COPY64)
-# define UA_GET64 ACC_UA_GET64
-# define UA_SET64 ACC_UA_SET64
-# define UA_COPY64 ACC_UA_COPY64
-# else
-# define UA_GET64(p) (* (__lzo_ua_volatile const lzo_uint64p) (__lzo_ua_volatile const lzo_voidp) (p))
-# define UA_SET64(p,v) ((* (__lzo_ua_volatile lzo_uint64p) (__lzo_ua_volatile lzo_voidp) (p)) = (lzo_uint64) (v))
-# define UA_COPY64(d,s) UA_SET64(d, UA_GET64(s))
-# endif
+#endif
+
+__lzo_static_forceinline unsigned lzo_bitops_ctlz32_func(lzo_uint32_t v)
+{
+#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386)
+ unsigned long r; (void) _BitScanReverse(&r, v); return (unsigned) r ^ 31;
+#define lzo_bitops_ctlz32(v) lzo_bitops_ctlz32_func(v)
+#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) && (LZO_ASM_SYNTAX_GNUC)
+ lzo_uint32_t r;
+ __asm__("bsr %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC);
+ return (unsigned) r ^ 31;
+#define lzo_bitops_ctlz32(v) lzo_bitops_ctlz32_func(v)
+#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_INT == 4)
+ unsigned r; r = (unsigned) __builtin_clz(v); return r;
+#define lzo_bitops_ctlz32(v) ((unsigned) __builtin_clz(v))
+#else
+ LZO_UNUSED(v); return 0;
+#endif
+}
+
+#if defined(lzo_uint64_t)
+__lzo_static_forceinline unsigned lzo_bitops_ctlz64_func(lzo_uint64_t v)
+{
+#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64)
+ unsigned long r; (void) _BitScanReverse64(&r, v); return (unsigned) r ^ 63;
+#define lzo_bitops_ctlz64(v) lzo_bitops_ctlz64_func(v)
+#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64) && (LZO_ASM_SYNTAX_GNUC)
+ lzo_uint64_t r;
+ __asm__("bsr %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC);
+ return (unsigned) r ^ 63;
+#define lzo_bitops_ctlz64(v) lzo_bitops_ctlz64_func(v)
+#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG == 8) && (LZO_WORDSIZE >= 8)
+ unsigned r; r = (unsigned) __builtin_clzl(v); return r;
+#define lzo_bitops_ctlz64(v) ((unsigned) __builtin_clzl(v))
+#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG_LONG == 8) && (LZO_WORDSIZE >= 8)
+ unsigned r; r = (unsigned) __builtin_clzll(v); return r;
+#define lzo_bitops_ctlz64(v) ((unsigned) __builtin_clzll(v))
+#else
+ LZO_UNUSED(v); return 0;
+#endif
+}
+#endif
+
+__lzo_static_forceinline unsigned lzo_bitops_cttz32_func(lzo_uint32_t v)
+{
+#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386)
+ unsigned long r; (void) _BitScanForward(&r, v); return (unsigned) r;
+#define lzo_bitops_cttz32(v) lzo_bitops_cttz32_func(v)
+#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) && (LZO_ASM_SYNTAX_GNUC)
+ lzo_uint32_t r;
+ __asm__("bsf %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC);
+ return (unsigned) r;
+#define lzo_bitops_cttz32(v) lzo_bitops_cttz32_func(v)
+#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_INT >= 4)
+ unsigned r; r = (unsigned) __builtin_ctz(v); return r;
+#define lzo_bitops_cttz32(v) ((unsigned) __builtin_ctz(v))
+#else
+ LZO_UNUSED(v); return 0;
+#endif
+}
+
+#if defined(lzo_uint64_t)
+__lzo_static_forceinline unsigned lzo_bitops_cttz64_func(lzo_uint64_t v)
+{
+#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64)
+ unsigned long r; (void) _BitScanForward64(&r, v); return (unsigned) r;
+#define lzo_bitops_cttz64(v) lzo_bitops_cttz64_func(v)
+#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64) && (LZO_ASM_SYNTAX_GNUC)
+ lzo_uint64_t r;
+ __asm__("bsf %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC);
+ return (unsigned) r;
+#define lzo_bitops_cttz64(v) lzo_bitops_cttz64_func(v)
+#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG >= 8) && (LZO_WORDSIZE >= 8)
+ unsigned r; r = (unsigned) __builtin_ctzl(v); return r;
+#define lzo_bitops_cttz64(v) ((unsigned) __builtin_ctzl(v))
+#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG_LONG >= 8) && (LZO_WORDSIZE >= 8)
+ unsigned r; r = (unsigned) __builtin_ctzll(v); return r;
+#define lzo_bitops_cttz64(v) ((unsigned) __builtin_ctzll(v))
+#else
+ LZO_UNUSED(v); return 0;
+#endif
+}
+#endif
+
+#if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+static void __attribute__((__unused__))
+#else
+__lzo_static_forceinline void
+#endif
+lzo_bitops_unused_funcs(void)
+{
+ LZO_UNUSED_FUNC(lzo_bitops_ctlz32_func);
+ LZO_UNUSED_FUNC(lzo_bitops_cttz32_func);
+#if defined(lzo_uint64_t)
+ LZO_UNUSED_FUNC(lzo_bitops_ctlz64_func);
+ LZO_UNUSED_FUNC(lzo_bitops_cttz64_func);
+#endif
+ LZO_UNUSED_FUNC(lzo_bitops_unused_funcs);
+}
+
+#if defined(__lzo_alignof) && !(LZO_CFG_NO_UNALIGNED)
+#ifndef __lzo_memops_tcheck
+#define __lzo_memops_tcheck(t,a,b) ((void)0, sizeof(t) == (a) && __lzo_alignof(t) == (b))
+#endif
+#endif
+#ifndef lzo_memops_TU0p
+#define lzo_memops_TU0p void __LZO_MMODEL *
+#endif
+#ifndef lzo_memops_TU1p
+#define lzo_memops_TU1p unsigned char __LZO_MMODEL *
+#endif
+#ifndef lzo_memops_TU2p
+#if (LZO_OPT_UNALIGNED16)
+typedef lzo_uint16_t __lzo_may_alias lzo_memops_TU2;
+#define lzo_memops_TU2p volatile lzo_memops_TU2 *
+#elif defined(__lzo_byte_struct)
+__lzo_byte_struct(lzo_memops_TU2_struct,2)
+typedef struct lzo_memops_TU2_struct lzo_memops_TU2;
+#else
+struct lzo_memops_TU2_struct { unsigned char a[2]; } __lzo_may_alias;
+typedef struct lzo_memops_TU2_struct lzo_memops_TU2;
+#endif
+#ifndef lzo_memops_TU2p
+#define lzo_memops_TU2p lzo_memops_TU2 *
+#endif
+#endif
+#ifndef lzo_memops_TU4p
+#if (LZO_OPT_UNALIGNED32)
+typedef lzo_uint32_t __lzo_may_alias lzo_memops_TU4;
+#define lzo_memops_TU4p volatile lzo_memops_TU4 __LZO_MMODEL *
+#elif defined(__lzo_byte_struct)
+__lzo_byte_struct(lzo_memops_TU4_struct,4)
+typedef struct lzo_memops_TU4_struct lzo_memops_TU4;
+#else
+struct lzo_memops_TU4_struct { unsigned char a[4]; } __lzo_may_alias;
+typedef struct lzo_memops_TU4_struct lzo_memops_TU4;
+#endif
+#ifndef lzo_memops_TU4p
+#define lzo_memops_TU4p lzo_memops_TU4 __LZO_MMODEL *
+#endif
+#endif
+#ifndef lzo_memops_TU8p
+#if (LZO_OPT_UNALIGNED64)
+typedef lzo_uint64_t __lzo_may_alias lzo_memops_TU8;
+#define lzo_memops_TU8p volatile lzo_memops_TU8 __LZO_MMODEL *
+#elif defined(__lzo_byte_struct)
+__lzo_byte_struct(lzo_memops_TU8_struct,8)
+typedef struct lzo_memops_TU8_struct lzo_memops_TU8;
+#else
+struct lzo_memops_TU8_struct { unsigned char a[8]; } __lzo_may_alias;
+typedef struct lzo_memops_TU8_struct lzo_memops_TU8;
+#endif
+#ifndef lzo_memops_TU8p
+#define lzo_memops_TU8p lzo_memops_TU8 __LZO_MMODEL *
+#endif
+#endif
+#ifndef lzo_memops_set_TU1p
+#define lzo_memops_set_TU1p volatile lzo_memops_TU1p
+#endif
+#ifndef lzo_memops_move_TU1p
+#define lzo_memops_move_TU1p lzo_memops_TU1p
+#endif
+#define LZO_MEMOPS_SET1(dd,cc) \
+ LZO_BLOCK_BEGIN \
+ lzo_memops_set_TU1p d__1 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \
+ d__1[0] = LZO_BYTE(cc); \
+ LZO_BLOCK_END
+#define LZO_MEMOPS_SET2(dd,cc) \
+ LZO_BLOCK_BEGIN \
+ lzo_memops_set_TU1p d__2 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \
+ d__2[0] = LZO_BYTE(cc); d__2[1] = LZO_BYTE(cc); \
+ LZO_BLOCK_END
+#define LZO_MEMOPS_SET3(dd,cc) \
+ LZO_BLOCK_BEGIN \
+ lzo_memops_set_TU1p d__3 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \
+ d__3[0] = LZO_BYTE(cc); d__3[1] = LZO_BYTE(cc); d__3[2] = LZO_BYTE(cc); \
+ LZO_BLOCK_END
+#define LZO_MEMOPS_SET4(dd,cc) \
+ LZO_BLOCK_BEGIN \
+ lzo_memops_set_TU1p d__4 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \
+ d__4[0] = LZO_BYTE(cc); d__4[1] = LZO_BYTE(cc); d__4[2] = LZO_BYTE(cc); d__4[3] = LZO_BYTE(cc); \
+ LZO_BLOCK_END
+#define LZO_MEMOPS_MOVE1(dd,ss) \
+ LZO_BLOCK_BEGIN \
+ lzo_memops_move_TU1p d__1 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \
+ const lzo_memops_move_TU1p s__1 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \
+ d__1[0] = s__1[0]; \
+ LZO_BLOCK_END
+#define LZO_MEMOPS_MOVE2(dd,ss) \
+ LZO_BLOCK_BEGIN \
+ lzo_memops_move_TU1p d__2 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \
+ const lzo_memops_move_TU1p s__2 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \
+ d__2[0] = s__2[0]; d__2[1] = s__2[1]; \
+ LZO_BLOCK_END
+#define LZO_MEMOPS_MOVE3(dd,ss) \
+ LZO_BLOCK_BEGIN \
+ lzo_memops_move_TU1p d__3 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \
+ const lzo_memops_move_TU1p s__3 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \
+ d__3[0] = s__3[0]; d__3[1] = s__3[1]; d__3[2] = s__3[2]; \
+ LZO_BLOCK_END
+#define LZO_MEMOPS_MOVE4(dd,ss) \
+ LZO_BLOCK_BEGIN \
+ lzo_memops_move_TU1p d__4 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \
+ const lzo_memops_move_TU1p s__4 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \
+ d__4[0] = s__4[0]; d__4[1] = s__4[1]; d__4[2] = s__4[2]; d__4[3] = s__4[3]; \
+ LZO_BLOCK_END
+#define LZO_MEMOPS_MOVE8(dd,ss) \
+ LZO_BLOCK_BEGIN \
+ lzo_memops_move_TU1p d__8 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \
+ const lzo_memops_move_TU1p s__8 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \
+ d__8[0] = s__8[0]; d__8[1] = s__8[1]; d__8[2] = s__8[2]; d__8[3] = s__8[3]; \
+ d__8[4] = s__8[4]; d__8[5] = s__8[5]; d__8[6] = s__8[6]; d__8[7] = s__8[7]; \
+ LZO_BLOCK_END
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU1p)0)==1)
+#define LZO_MEMOPS_COPY1(dd,ss) LZO_MEMOPS_MOVE1(dd,ss)
+#if (LZO_OPT_UNALIGNED16)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU2p)0)==2)
+#define LZO_MEMOPS_COPY2(dd,ss) \
+ * (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss)
+#elif defined(__lzo_memops_tcheck)
+#define LZO_MEMOPS_COPY2(dd,ss) \
+ LZO_BLOCK_BEGIN if (__lzo_memops_tcheck(lzo_memops_TU2,2,1)) { \
+ * (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss); \
+ } else { LZO_MEMOPS_MOVE2(dd,ss); } LZO_BLOCK_END
+#else
+#define LZO_MEMOPS_COPY2(dd,ss) LZO_MEMOPS_MOVE2(dd,ss)
+#endif
+#if (LZO_OPT_UNALIGNED32)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU4p)0)==4)
+#define LZO_MEMOPS_COPY4(dd,ss) \
+ * (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss)
+#elif defined(__lzo_memops_tcheck)
+#define LZO_MEMOPS_COPY4(dd,ss) \
+ LZO_BLOCK_BEGIN if (__lzo_memops_tcheck(lzo_memops_TU4,4,1)) { \
+ * (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss); \
+ } else { LZO_MEMOPS_MOVE4(dd,ss); } LZO_BLOCK_END
+#else
+#define LZO_MEMOPS_COPY4(dd,ss) LZO_MEMOPS_MOVE4(dd,ss)
+#endif
+#if (LZO_WORDSIZE != 8)
+#define LZO_MEMOPS_COPY8(dd,ss) \
+ LZO_BLOCK_BEGIN LZO_MEMOPS_COPY4(dd,ss); LZO_MEMOPS_COPY4((lzo_memops_TU1p)(lzo_memops_TU0p)(dd)+4,(const lzo_memops_TU1p)(const lzo_memops_TU0p)(ss)+4); LZO_BLOCK_END
+#else
+#if (LZO_OPT_UNALIGNED64)
+LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU8p)0)==8)
+#define LZO_MEMOPS_COPY8(dd,ss) \
+ * (lzo_memops_TU8p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss)
+#elif (LZO_OPT_UNALIGNED32)
+#define LZO_MEMOPS_COPY8(dd,ss) \
+ LZO_BLOCK_BEGIN LZO_MEMOPS_COPY4(dd,ss); LZO_MEMOPS_COPY4((lzo_memops_TU1p)(lzo_memops_TU0p)(dd)+4,(const lzo_memops_TU1p)(const lzo_memops_TU0p)(ss)+4); LZO_BLOCK_END
+#elif defined(__lzo_memops_tcheck)
+#define LZO_MEMOPS_COPY8(dd,ss) \
+ LZO_BLOCK_BEGIN if (__lzo_memops_tcheck(lzo_memops_TU8,8,1)) { \
+ * (lzo_memops_TU8p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss); \
+ } else { LZO_MEMOPS_MOVE8(dd,ss); } LZO_BLOCK_END
+#else
+#define LZO_MEMOPS_COPY8(dd,ss) LZO_MEMOPS_MOVE8(dd,ss)
+#endif
+#endif
+#define LZO_MEMOPS_COPYN(dd,ss,nn) \
+ LZO_BLOCK_BEGIN \
+ lzo_memops_TU1p d__n = (lzo_memops_TU1p) (lzo_memops_TU0p) (dd); \
+ const lzo_memops_TU1p s__n = (const lzo_memops_TU1p) (const lzo_memops_TU0p) (ss); \
+ lzo_uint n__n = (nn); \
+ while ((void)0, n__n >= 8) { LZO_MEMOPS_COPY8(d__n, s__n); d__n += 8; s__n += 8; n__n -= 8; } \
+ if ((void)0, n__n >= 4) { LZO_MEMOPS_COPY4(d__n, s__n); d__n += 4; s__n += 4; n__n -= 4; } \
+ if ((void)0, n__n > 0) do { *d__n++ = *s__n++; } while (--n__n > 0); \
+ LZO_BLOCK_END
+
+__lzo_static_forceinline lzo_uint16_t lzo_memops_get_le16(const lzo_voidp ss)
+{
+ lzo_uint16_t v;
+#if (LZO_ABI_LITTLE_ENDIAN)
+ LZO_MEMOPS_COPY2(&v, ss);
+#elif (LZO_OPT_UNALIGNED16 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC)
+ const lzo_memops_TU2p s = (const lzo_memops_TU2p) ss;
+ unsigned long vv;
+ __asm__("lhbrx %0,0,%1" : "=r" (vv) : "r" (s), "m" (*s));
+ v = (lzo_uint16_t) vv;
+#else
+ const lzo_memops_TU1p s = (const lzo_memops_TU1p) ss;
+ v = (lzo_uint16_t) (((lzo_uint16_t)s[0]) | ((lzo_uint16_t)s[1] << 8));
+#endif
+ return v;
+}
+#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
+#define LZO_MEMOPS_GET_LE16(ss) * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss)
+#else
+#define LZO_MEMOPS_GET_LE16(ss) lzo_memops_get_le16(ss)
+#endif
+
+__lzo_static_forceinline lzo_uint32_t lzo_memops_get_le32(const lzo_voidp ss)
+{
+ lzo_uint32_t v;
+#if (LZO_ABI_LITTLE_ENDIAN)
+ LZO_MEMOPS_COPY4(&v, ss);
+#elif (LZO_OPT_UNALIGNED32 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC)
+ const lzo_memops_TU4p s = (const lzo_memops_TU4p) ss;
+ unsigned long vv;
+ __asm__("lwbrx %0,0,%1" : "=r" (vv) : "r" (s), "m" (*s));
+ v = (lzo_uint32_t) vv;
+#else
+ const lzo_memops_TU1p s = (const lzo_memops_TU1p) ss;
+ v = (lzo_uint32_t) (((lzo_uint32_t)s[0]) | ((lzo_uint32_t)s[1] << 8) | ((lzo_uint32_t)s[2] << 16) | ((lzo_uint32_t)s[3] << 24));
+#endif
+ return v;
+}
+#if (LZO_OPT_UNALIGNED32) && (LZO_ABI_LITTLE_ENDIAN)
+#define LZO_MEMOPS_GET_LE32(ss) * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss)
+#else
+#define LZO_MEMOPS_GET_LE32(ss) lzo_memops_get_le32(ss)
+#endif
+
+#if (LZO_OPT_UNALIGNED64) && (LZO_ABI_LITTLE_ENDIAN)
+#define LZO_MEMOPS_GET_LE64(ss) * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss)
+#endif
+
+__lzo_static_forceinline lzo_uint16_t lzo_memops_get_ne16(const lzo_voidp ss)
+{
+ lzo_uint16_t v;
+ LZO_MEMOPS_COPY2(&v, ss);
+ return v;
+}
+#if (LZO_OPT_UNALIGNED16)
+#define LZO_MEMOPS_GET_NE16(ss) * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss)
+#else
+#define LZO_MEMOPS_GET_NE16(ss) lzo_memops_get_ne16(ss)
+#endif
+
+__lzo_static_forceinline lzo_uint32_t lzo_memops_get_ne32(const lzo_voidp ss)
+{
+ lzo_uint32_t v;
+ LZO_MEMOPS_COPY4(&v, ss);
+ return v;
+}
+#if (LZO_OPT_UNALIGNED32)
+#define LZO_MEMOPS_GET_NE32(ss) * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss)
+#else
+#define LZO_MEMOPS_GET_NE32(ss) lzo_memops_get_ne32(ss)
+#endif
+
+#if (LZO_OPT_UNALIGNED64)
+#define LZO_MEMOPS_GET_NE64(ss) * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss)
+#endif
+
+__lzo_static_forceinline void lzo_memops_put_le16(lzo_voidp dd, lzo_uint16_t vv)
+{
+#if (LZO_ABI_LITTLE_ENDIAN)
+ LZO_MEMOPS_COPY2(dd, &vv);
+#elif (LZO_OPT_UNALIGNED16 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC)
+ lzo_memops_TU2p d = (lzo_memops_TU2p) dd;
+ unsigned long v = vv;
+ __asm__("sthbrx %2,0,%1" : "=m" (*d) : "r" (d), "r" (v));
+#else
+ lzo_memops_TU1p d = (lzo_memops_TU1p) dd;
+ d[0] = LZO_BYTE((vv ) & 0xff);
+ d[1] = LZO_BYTE((vv >> 8) & 0xff);
+#endif
+}
+#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
+#define LZO_MEMOPS_PUT_LE16(dd,vv) (* (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = (vv))
+#else
+#define LZO_MEMOPS_PUT_LE16(dd,vv) lzo_memops_put_le16(dd,vv)
+#endif
+
+__lzo_static_forceinline void lzo_memops_put_le32(lzo_voidp dd, lzo_uint32_t vv)
+{
+#if (LZO_ABI_LITTLE_ENDIAN)
+ LZO_MEMOPS_COPY4(dd, &vv);
+#elif (LZO_OPT_UNALIGNED32 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC)
+ lzo_memops_TU4p d = (lzo_memops_TU4p) dd;
+ unsigned long v = vv;
+ __asm__("stwbrx %2,0,%1" : "=m" (*d) : "r" (d), "r" (v));
+#else
+ lzo_memops_TU1p d = (lzo_memops_TU1p) dd;
+ d[0] = LZO_BYTE((vv ) & 0xff);
+ d[1] = LZO_BYTE((vv >> 8) & 0xff);
+ d[2] = LZO_BYTE((vv >> 16) & 0xff);
+ d[3] = LZO_BYTE((vv >> 24) & 0xff);
+#endif
+}
+#if (LZO_OPT_UNALIGNED32) && (LZO_ABI_LITTLE_ENDIAN)
+#define LZO_MEMOPS_PUT_LE32(dd,vv) (* (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = (vv))
+#else
+#define LZO_MEMOPS_PUT_LE32(dd,vv) lzo_memops_put_le32(dd,vv)
+#endif
+
+__lzo_static_forceinline void lzo_memops_put_ne16(lzo_voidp dd, lzo_uint16_t vv)
+{
+ LZO_MEMOPS_COPY2(dd, &vv);
+}
+#if (LZO_OPT_UNALIGNED16)
+#define LZO_MEMOPS_PUT_NE16(dd,vv) (* (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = (vv))
+#else
+#define LZO_MEMOPS_PUT_NE16(dd,vv) lzo_memops_put_ne16(dd,vv)
+#endif
+
+__lzo_static_forceinline void lzo_memops_put_ne32(lzo_voidp dd, lzo_uint32_t vv)
+{
+ LZO_MEMOPS_COPY4(dd, &vv);
+}
+#if (LZO_OPT_UNALIGNED32)
+#define LZO_MEMOPS_PUT_NE32(dd,vv) (* (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = (vv))
+#else
+#define LZO_MEMOPS_PUT_NE32(dd,vv) lzo_memops_put_ne32(dd,vv)
+#endif
+
+#if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI)
+static void __attribute__((__unused__))
+#else
+__lzo_static_forceinline void
+#endif
+lzo_memops_unused_funcs(void)
+{
+ LZO_UNUSED_FUNC(lzo_memops_get_le16);
+ LZO_UNUSED_FUNC(lzo_memops_get_le32);
+ LZO_UNUSED_FUNC(lzo_memops_get_ne16);
+ LZO_UNUSED_FUNC(lzo_memops_get_ne32);
+ LZO_UNUSED_FUNC(lzo_memops_put_le16);
+ LZO_UNUSED_FUNC(lzo_memops_put_le32);
+ LZO_UNUSED_FUNC(lzo_memops_put_ne16);
+ LZO_UNUSED_FUNC(lzo_memops_put_ne32);
+ LZO_UNUSED_FUNC(lzo_memops_unused_funcs);
+}
+
+#endif
+
+#ifndef UA_SET1
+#define UA_SET1 LZO_MEMOPS_SET1
+#endif
+#ifndef UA_SET2
+#define UA_SET2 LZO_MEMOPS_SET2
+#endif
+#ifndef UA_SET3
+#define UA_SET3 LZO_MEMOPS_SET3
+#endif
+#ifndef UA_SET4
+#define UA_SET4 LZO_MEMOPS_SET4
+#endif
+#ifndef UA_MOVE1
+#define UA_MOVE1 LZO_MEMOPS_MOVE1
+#endif
+#ifndef UA_MOVE2
+#define UA_MOVE2 LZO_MEMOPS_MOVE2
+#endif
+#ifndef UA_MOVE3
+#define UA_MOVE3 LZO_MEMOPS_MOVE3
+#endif
+#ifndef UA_MOVE4
+#define UA_MOVE4 LZO_MEMOPS_MOVE4
+#endif
+#ifndef UA_MOVE8
+#define UA_MOVE8 LZO_MEMOPS_MOVE8
+#endif
+#ifndef UA_COPY1
+#define UA_COPY1 LZO_MEMOPS_COPY1
+#endif
+#ifndef UA_COPY2
+#define UA_COPY2 LZO_MEMOPS_COPY2
+#endif
+#ifndef UA_COPY3
+#define UA_COPY3 LZO_MEMOPS_COPY3
+#endif
+#ifndef UA_COPY4
+#define UA_COPY4 LZO_MEMOPS_COPY4
+#endif
+#ifndef UA_COPY8
+#define UA_COPY8 LZO_MEMOPS_COPY8
+#endif
+#ifndef UA_COPYN
+#define UA_COPYN LZO_MEMOPS_COPYN
+#endif
+#ifndef UA_COPYN_X
+#define UA_COPYN_X LZO_MEMOPS_COPYN
+#endif
+#ifndef UA_GET_LE16
+#define UA_GET_LE16 LZO_MEMOPS_GET_LE16
+#endif
+#ifndef UA_GET_LE32
+#define UA_GET_LE32 LZO_MEMOPS_GET_LE32
+#endif
+#ifdef LZO_MEMOPS_GET_LE64
+#ifndef UA_GET_LE64
+#define UA_GET_LE64 LZO_MEMOPS_GET_LE64
+#endif
+#endif
+#ifndef UA_GET_NE16
+#define UA_GET_NE16 LZO_MEMOPS_GET_NE16
+#endif
+#ifndef UA_GET_NE32
+#define UA_GET_NE32 LZO_MEMOPS_GET_NE32
+#endif
+#ifdef LZO_MEMOPS_GET_NE64
+#ifndef UA_GET_NE64
+#define UA_GET_NE64 LZO_MEMOPS_GET_NE64
+#endif
+#endif
+#ifndef UA_PUT_LE16
+#define UA_PUT_LE16 LZO_MEMOPS_PUT_LE16
+#endif
+#ifndef UA_PUT_LE32
+#define UA_PUT_LE32 LZO_MEMOPS_PUT_LE32
+#endif
+#ifndef UA_PUT_NE16
+#define UA_PUT_NE16 LZO_MEMOPS_PUT_NE16
+#endif
+#ifndef UA_PUT_NE32
+#define UA_PUT_NE32 LZO_MEMOPS_PUT_NE32
#endif
#define MEMCPY8_DS(dest,src,len) \
@@ -2195,25 +3782,10 @@ LZO_EXTERN(const lzo_bytep) lzo_copyright(void);
extern "C" {
#endif
-#if !defined(lzo_uintptr_t)
-# if (__LZO_MMODEL_HUGE)
-# define lzo_uintptr_t unsigned long
-# else
-# define lzo_uintptr_t acc_uintptr_t
-# ifdef __ACC_INTPTR_T_IS_POINTER
-# define __LZO_UINTPTR_T_IS_POINTER 1
-# endif
-# endif
-#endif
-
#if (LZO_ARCH_I086)
-#define PTR(a) ((lzo_bytep) (a))
-#define PTR_ALIGNED_4(a) ((ACC_PTR_FP_OFF(a) & 3) == 0)
-#define PTR_ALIGNED2_4(a,b) (((ACC_PTR_FP_OFF(a) | ACC_PTR_FP_OFF(b)) & 3) == 0)
+#error "LZO_ARCH_I086 is unsupported"
#elif (LZO_MM_PVP)
-#define PTR(a) ((lzo_bytep) (a))
-#define PTR_ALIGNED_8(a) ((((lzo_uintptr_t)(a)) >> 61) == 0)
-#define PTR_ALIGNED2_8(a,b) ((((lzo_uintptr_t)(a)|(lzo_uintptr_t)(b)) >> 61) == 0)
+#error "LZO_MM_PVP is unsupported"
#else
#define PTR(a) ((lzo_uintptr_t) (a))
#define PTR_LINEAR(a) PTR(a)
@@ -2243,24 +3815,28 @@ typedef union
unsigned long a_ulong;
lzo_int a_lzo_int;
lzo_uint a_lzo_uint;
- lzo_int32 a_lzo_int32;
- lzo_uint32 a_lzo_uint32;
-#if defined(LZO_UINT64_MAX)
- lzo_int64 a_lzo_int64;
- lzo_uint64 a_lzo_uint64;
-#endif
+ lzo_xint a_lzo_xint;
+ lzo_int16_t a_lzo_int16_t;
+ lzo_uint16_t a_lzo_uint16_t;
+ lzo_int32_t a_lzo_int32_t;
+ lzo_uint32_t a_lzo_uint32_t;
+#if defined(lzo_uint64_t)
+ lzo_int64_t a_lzo_int64_t;
+ lzo_uint64_t a_lzo_uint64_t;
+#endif
+ size_t a_size_t;
ptrdiff_t a_ptrdiff_t;
lzo_uintptr_t a_lzo_uintptr_t;
- lzo_voidp a_lzo_voidp;
void * a_void_p;
- lzo_bytep a_lzo_bytep;
- lzo_bytepp a_lzo_bytepp;
- lzo_uintp a_lzo_uintp;
- lzo_uint * a_lzo_uint_p;
- lzo_uint32p a_lzo_uint32p;
- lzo_uint32 * a_lzo_uint32_p;
- unsigned char * a_uchar_p;
char * a_char_p;
+ unsigned char * a_uchar_p;
+ const void * a_c_void_p;
+ const char * a_c_char_p;
+ const unsigned char * a_c_uchar_p;
+ lzo_voidp a_lzo_voidp;
+ lzo_bytep a_lzo_bytep;
+ const lzo_voidp a_c_lzo_voidp;
+ const lzo_bytep a_c_lzo_bytep;
}
lzo_full_align_t;
@@ -2276,18 +3852,14 @@ lzo_full_align_t;
#ifndef LZO_DICT_USE_PTR
#define LZO_DICT_USE_PTR 1
-#if 0 && (LZO_ARCH_I086)
-# undef LZO_DICT_USE_PTR
-# define LZO_DICT_USE_PTR 0
-#endif
#endif
#if (LZO_DICT_USE_PTR)
# define lzo_dict_t const lzo_bytep
-# define lzo_dict_p lzo_dict_t __LZO_MMODEL *
+# define lzo_dict_p lzo_dict_t *
#else
# define lzo_dict_t lzo_uint
-# define lzo_dict_p lzo_dict_t __LZO_MMODEL *
+# define lzo_dict_p lzo_dict_t *
#endif
#endif
@@ -2300,10 +3872,9 @@ __lzo_ptr_linear(const lzo_voidp ptr)
lzo_uintptr_t p;
#if (LZO_ARCH_I086)
- p = (((lzo_uintptr_t)(ACC_PTR_FP_SEG(ptr))) << (16 - ACC_MM_AHSHIFT)) + (ACC_PTR_FP_OFF(ptr));
+#error "LZO_ARCH_I086 is unsupported"
#elif (LZO_MM_PVP)
- p = (lzo_uintptr_t) (ptr);
- p = (p << 3) | (p >> 61);
+#error "LZO_MM_PVP is unsupported"
#else
p = (lzo_uintptr_t) PTR_LINEAR(ptr);
#endif
@@ -2314,9 +3885,8 @@ __lzo_ptr_linear(const lzo_voidp ptr)
LZO_PUBLIC(unsigned)
__lzo_align_gap(const lzo_voidp ptr, lzo_uint size)
{
-#if defined(__LZO_UINTPTR_T_IS_POINTER)
- size_t n = (size_t) ptr;
- n = (((n + size - 1) / size) * size) - n;
+#if (__LZO_UINTPTR_T_IS_POINTER)
+#error "__LZO_UINTPTR_T_IS_POINTER is unsupported"
#else
lzo_uintptr_t p, n;
p = __lzo_ptr_linear(ptr);
@@ -2342,7 +3912,7 @@ static const char __lzo_copyright[] =
#else
"\r\n\n"
"LZO data compression library.\n"
- "$Copyright: LZO Copyright (C) 1996-2011 Markus Franz Xaver Johannes Oberhumer\n"
+ "$Copyright: LZO Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer\n"
"<markus@oberhumer.com>\n"
"http://www.oberhumer.com $\n\n"
"$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n"
@@ -2352,11 +3922,7 @@ static const char __lzo_copyright[] =
LZO_PUBLIC(const lzo_bytep)
lzo_copyright(void)
{
-#if (LZO_OS_DOS16 && LZO_CC_TURBOC)
- return (lzo_voidp) __lzo_copyright;
-#else
return (const lzo_bytep) __lzo_copyright;
-#endif
}
LZO_PUBLIC(unsigned)
@@ -2393,16 +3959,16 @@ _lzo_version_date(void)
#define LZO_NMAX 5552
#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1
-#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1);
-#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2);
-#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4);
-#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8);
+#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1)
+#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2)
+#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4)
+#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8)
-LZO_PUBLIC(lzo_uint32)
-lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len)
+LZO_PUBLIC(lzo_uint32_t)
+lzo_adler32(lzo_uint32_t adler, const lzo_bytep buf, lzo_uint len)
{
- lzo_uint32 s1 = adler & 0xffff;
- lzo_uint32 s2 = (adler >> 16) & 0xffff;
+ lzo_uint32_t s1 = adler & 0xffff;
+ lzo_uint32_t s2 = (adler >> 16) & 0xffff;
unsigned k;
if (buf == NULL)
@@ -2459,8 +4025,8 @@ lzo_adler32(lzo_uint32 adler, const lzo_bytep buf, lzo_uint len)
LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len)
{
#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCMP)
- const lzo_hbyte_p p1 = (const lzo_hbyte_p) s1;
- const lzo_hbyte_p p2 = (const lzo_hbyte_p) s2;
+ const lzo_hbyte_p p1 = LZO_STATIC_CAST(const lzo_hbyte_p, s1);
+ const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, s2);
if __lzo_likely(len > 0) do
{
int d = *p1 - *p2;
@@ -2476,8 +4042,8 @@ LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo
LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len)
{
#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCPY)
- lzo_hbyte_p p1 = (lzo_hbyte_p) dest;
- const lzo_hbyte_p p2 = (const lzo_hbyte_p) src;
+ lzo_hbyte_p p1 = LZO_STATIC_CAST(lzo_hbyte_p, dest);
+ const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, src);
if (!(len > 0) || p1 == p2)
return dest;
do
@@ -2491,8 +4057,8 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src
LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len)
{
#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMMOVE)
- lzo_hbyte_p p1 = (lzo_hbyte_p) dest;
- const lzo_hbyte_p p2 = (const lzo_hbyte_p) src;
+ lzo_hbyte_p p1 = LZO_STATIC_CAST(lzo_hbyte_p, dest);
+ const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, src);
if (!(len > 0) || p1 == p2)
return dest;
if (p1 < p2)
@@ -2514,16 +4080,17 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p sr
return memmove(dest, src, len);
#endif
}
-LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len)
+LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int cc, lzo_hsize_t len)
{
#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMSET)
- lzo_hbyte_p p = (lzo_hbyte_p) s;
+ lzo_hbyte_p p = LZO_STATIC_CAST(lzo_hbyte_p, s);
+ unsigned char c = LZO_ITRUNC(unsigned char, cc);
if __lzo_likely(len > 0) do
- *p++ = (unsigned char) c;
+ *p++ = c;
while __lzo_likely(--len > 0);
return s;
#else
- return memset(s, c, len);
+ return memset(s, cc, len);
#endif
}
#undef LZOLIB_PUBLIC
@@ -2532,103 +4099,28 @@ LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int c, lzo_hsize_t len)
#if !defined(__LZO_IN_MINILZO)
-#define ACC_WANT_ACC_CHK_CH 1
-#undef ACCCHK_ASSERT
-
- ACCCHK_ASSERT_IS_SIGNED_T(lzo_int)
- ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint)
-
- ACCCHK_ASSERT_IS_SIGNED_T(lzo_int32)
- ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint32)
- ACCCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0)
- ACCCHK_ASSERT(sizeof(lzo_uint32) >= 4)
-#if defined(LZO_UINT64_MAX)
- ACCCHK_ASSERT(sizeof(lzo_uint64) == 8)
- ACCCHK_ASSERT_IS_SIGNED_T(lzo_int64)
- ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uint64)
-#endif
-
-#if !defined(__LZO_UINTPTR_T_IS_POINTER)
- ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t)
-#endif
- ACCCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
-
- ACCCHK_ASSERT_IS_UNSIGNED_T(lzo_xint)
- ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint32))
- ACCCHK_ASSERT(sizeof(lzo_xint) >= sizeof(lzo_uint))
- ACCCHK_ASSERT(sizeof(lzo_xint) == sizeof(lzo_uint32) || sizeof(lzo_xint) == sizeof(lzo_uint))
+#define LZO_WANT_ACC_CHK_CH 1
+#undef LZOCHK_ASSERT
+ LZOCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0)
+ LZOCHK_ASSERT_IS_SIGNED_T(lzo_int)
+ LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_uint)
+#if !(__LZO_UINTPTR_T_IS_POINTER)
+ LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t)
#endif
-#undef ACCCHK_ASSERT
+ LZOCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp))
+ LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_xint)
-#define WANT_lzo_bitops_clz32 1
-#define WANT_lzo_bitops_clz64 1
-#define WANT_lzo_bitops_ctz32 1
-#define WANT_lzo_bitops_ctz64 1
-
-#if (defined(_WIN32) || defined(_WIN64)) && ((LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_MSC && (_MSC_VER >= 1400)))
-#include <intrin.h>
-#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) && 0
-#pragma intrinsic(_BitScanReverse)
-static __lzo_inline unsigned lzo_bitops_clz32(lzo_uint32 v)
-{
- unsigned long r;
- (void) _BitScanReverse(&r, v);
- return (unsigned) r;
-}
-#define lzo_bitops_clz32 lzo_bitops_clz32
-#endif
-#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) && 0
-#pragma intrinsic(_BitScanReverse64)
-static __lzo_inline unsigned lzo_bitops_clz64(lzo_uint64 v)
-{
- unsigned long r;
- (void) _BitScanReverse64(&r, v);
- return (unsigned) r;
-}
-#define lzo_bitops_clz64 lzo_bitops_clz64
-#endif
-#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32)
-#pragma intrinsic(_BitScanForward)
-static __lzo_inline unsigned lzo_bitops_ctz32(lzo_uint32 v)
-{
- unsigned long r;
- (void) _BitScanForward(&r, v);
- return (unsigned) r;
-}
-#define lzo_bitops_ctz32 lzo_bitops_ctz32
-#endif
-#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX)
-#pragma intrinsic(_BitScanForward64)
-static __lzo_inline unsigned lzo_bitops_ctz64(lzo_uint64 v)
-{
- unsigned long r;
- (void) _BitScanForward64(&r, v);
- return (unsigned) r;
-}
-#define lzo_bitops_ctz64 lzo_bitops_ctz64
#endif
+#undef LZOCHK_ASSERT
-#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_LLVM && (!defined(__llvm_tools_version__) || (__llvm_tools_version__+0 >= 0x010500ul))))
-#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32)
-#define lzo_bitops_clz32(v) ((unsigned) __builtin_clz(v))
-#endif
-#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX)
-#define lzo_bitops_clz64(v) ((unsigned) __builtin_clzll(v))
-#endif
-#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32)
-#define lzo_bitops_ctz32(v) ((unsigned) __builtin_ctz(v))
-#endif
-#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX)
-#define lzo_bitops_ctz64(v) ((unsigned) __builtin_ctzll(v))
-#endif
-#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount32)
-#define lzo_bitops_popcount32(v) ((unsigned) __builtin_popcount(v))
-#endif
-#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount64) && defined(LZO_UINT64_MAX)
-#define lzo_bitops_popcount64(v) ((unsigned) __builtin_popcountll(v))
-#endif
+union lzo_config_check_union {
+ lzo_uint a[2];
+ unsigned char b[2*LZO_MAX(8,sizeof(lzo_uint))];
+#if defined(lzo_uint64_t)
+ lzo_uint64_t c[2];
#endif
+};
#if 0
#define u2p(ptr,off) ((lzo_voidp) (((lzo_bytep)(lzo_voidp)(ptr)) + (off)))
@@ -2642,73 +4134,101 @@ static __lzo_noinline lzo_voidp u2p(lzo_voidp ptr, lzo_uint off)
LZO_PUBLIC(int)
_lzo_config_check(void)
{
- lzo_bool r = 1;
- union {
- lzo_xint a[2]; unsigned char b[2*LZO_MAX(8,sizeof(lzo_xint))];
-#if defined(LZO_UNALIGNED_OK_8)
- lzo_uint64 c[2];
-#endif
- unsigned short x[2]; lzo_uint32 y[2]; lzo_uint z[2];
- } u;
+#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030100ul && LZO_CC_CLANG < 0x030300ul))
+# if 0
+ volatile
+# endif
+#endif
+ union lzo_config_check_union u;
lzo_voidp p;
+ unsigned r = 1;
u.a[0] = u.a[1] = 0;
p = u2p(&u, 0);
r &= ((* (lzo_bytep) p) == 0);
-#if !defined(LZO_CFG_NO_CONFIG_CHECK)
-#if defined(LZO_ABI_BIG_ENDIAN)
+#if !(LZO_CFG_NO_CONFIG_CHECK)
+#if (LZO_ABI_BIG_ENDIAN)
u.a[0] = u.a[1] = 0; u.b[sizeof(lzo_uint) - 1] = 128;
p = u2p(&u, 0);
r &= ((* (lzo_uintp) p) == 128);
#endif
-#if defined(LZO_ABI_LITTLE_ENDIAN)
+#if (LZO_ABI_LITTLE_ENDIAN)
u.a[0] = u.a[1] = 0; u.b[0] = 128;
p = u2p(&u, 0);
r &= ((* (lzo_uintp) p) == 128);
#endif
-#if defined(LZO_UNALIGNED_OK_2)
u.a[0] = u.a[1] = 0;
- u.b[0] = 1; u.b[sizeof(unsigned short) + 1] = 2;
+ u.b[0] = 1; u.b[3] = 2;
p = u2p(&u, 1);
- r &= ((* (lzo_ushortp) p) == 0);
+ r &= UA_GET_NE16(p) == 0;
+ r &= UA_GET_LE16(p) == 0;
+ u.b[1] = 128;
+ r &= UA_GET_LE16(p) == 128;
+ u.b[2] = 129;
+ r &= UA_GET_LE16(p) == LZO_UINT16_C(0x8180);
+#if (LZO_ABI_BIG_ENDIAN)
+ r &= UA_GET_NE16(p) == LZO_UINT16_C(0x8081);
+#endif
+#if (LZO_ABI_LITTLE_ENDIAN)
+ r &= UA_GET_NE16(p) == LZO_UINT16_C(0x8180);
#endif
-#if defined(LZO_UNALIGNED_OK_4)
u.a[0] = u.a[1] = 0;
- u.b[0] = 3; u.b[sizeof(lzo_uint32) + 1] = 4;
+ u.b[0] = 3; u.b[5] = 4;
p = u2p(&u, 1);
- r &= ((* (lzo_uint32p) p) == 0);
+ r &= UA_GET_NE32(p) == 0;
+ r &= UA_GET_LE32(p) == 0;
+ u.b[1] = 128;
+ r &= UA_GET_LE32(p) == 128;
+ u.b[2] = 129; u.b[3] = 130; u.b[4] = 131;
+ r &= UA_GET_LE32(p) == LZO_UINT32_C(0x83828180);
+#if (LZO_ABI_BIG_ENDIAN)
+ r &= UA_GET_NE32(p) == LZO_UINT32_C(0x80818283);
#endif
-#if defined(LZO_UNALIGNED_OK_8)
+#if (LZO_ABI_LITTLE_ENDIAN)
+ r &= UA_GET_NE32(p) == LZO_UINT32_C(0x83828180);
+#endif
+#if defined(UA_GET_NE64)
u.c[0] = u.c[1] = 0;
- u.b[0] = 5; u.b[sizeof(lzo_uint64) + 1] = 6;
+ u.b[0] = 5; u.b[9] = 6;
p = u2p(&u, 1);
- r &= ((* (lzo_uint64p) p) == 0);
-#endif
-#if defined(lzo_bitops_clz32)
- { unsigned i; lzo_uint32 v = 1;
- for (i = 0; i < 32; i++, v <<= 1)
- r &= lzo_bitops_clz32(v) == 31 - i;
- }
-#endif
-#if defined(lzo_bitops_clz64)
- { unsigned i; lzo_uint64 v = 1;
- for (i = 0; i < 64; i++, v <<= 1)
- r &= lzo_bitops_clz64(v) == 63 - i;
- }
-#endif
-#if defined(lzo_bitops_ctz32)
- { unsigned i; lzo_uint32 v = 1;
- for (i = 0; i < 32; i++, v <<= 1)
- r &= lzo_bitops_ctz32(v) == i;
- }
-#endif
-#if defined(lzo_bitops_ctz64)
- { unsigned i; lzo_uint64 v = 1;
- for (i = 0; i < 64; i++, v <<= 1)
- r &= lzo_bitops_ctz64(v) == i;
- }
-#endif
-#endif
+ u.c[0] = u.c[1] = 0;
+ r &= UA_GET_NE64(p) == 0;
+#if defined(UA_GET_LE64)
+ r &= UA_GET_LE64(p) == 0;
+ u.b[1] = 128;
+ r &= UA_GET_LE64(p) == 128;
+#endif
+#endif
+#if defined(lzo_bitops_ctlz32)
+ { unsigned i = 0; lzo_uint32_t v;
+ for (v = 1; v != 0 && r == 1; v <<= 1, i++) {
+ r &= lzo_bitops_ctlz32(v) == 31 - i;
+ r &= lzo_bitops_ctlz32_func(v) == 31 - i;
+ }}
+#endif
+#if defined(lzo_bitops_ctlz64)
+ { unsigned i = 0; lzo_uint64_t v;
+ for (v = 1; v != 0 && r == 1; v <<= 1, i++) {
+ r &= lzo_bitops_ctlz64(v) == 63 - i;
+ r &= lzo_bitops_ctlz64_func(v) == 63 - i;
+ }}
+#endif
+#if defined(lzo_bitops_cttz32)
+ { unsigned i = 0; lzo_uint32_t v;
+ for (v = 1; v != 0 && r == 1; v <<= 1, i++) {
+ r &= lzo_bitops_cttz32(v) == i;
+ r &= lzo_bitops_cttz32_func(v) == i;
+ }}
+#endif
+#if defined(lzo_bitops_cttz64)
+ { unsigned i = 0; lzo_uint64_t v;
+ for (v = 1; v != 0 && r == 1; v <<= 1, i++) {
+ r &= lzo_bitops_cttz64(v) == i;
+ r &= lzo_bitops_cttz64_func(v) == i;
+ }}
+#endif
+#endif
+ LZO_UNUSED_FUNC(lzo_bitops_unused_funcs);
return r == 1 ? LZO_E_OK : LZO_E_ERROR;
}
@@ -2722,11 +4242,11 @@ __lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5,
#if defined(__LZO_IN_MINILZO)
#elif (LZO_CC_MSC && ((_MSC_VER) < 700))
#else
-#define ACC_WANT_ACC_CHK_CH 1
-#undef ACCCHK_ASSERT
-#define ACCCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr)
+#define LZO_WANT_ACC_CHK_CH 1
+#undef LZOCHK_ASSERT
+#define LZOCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr)
#endif
-#undef ACCCHK_ASSERT
+#undef LZOCHK_ASSERT
if (v == 0)
return LZO_E_ERROR;
@@ -2734,7 +4254,7 @@ __lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5,
r = (s1 == -1 || s1 == (int) sizeof(short)) &&
(s2 == -1 || s2 == (int) sizeof(int)) &&
(s3 == -1 || s3 == (int) sizeof(long)) &&
- (s4 == -1 || s4 == (int) sizeof(lzo_uint32)) &&
+ (s4 == -1 || s4 == (int) sizeof(lzo_uint32_t)) &&
(s5 == -1 || s5 == (int) sizeof(lzo_uint)) &&
(s6 == -1 || s6 == (int) lzo_sizeof_dict_t) &&
(s7 == -1 || s7 == (int) sizeof(char *)) &&
@@ -2777,11 +4297,11 @@ int __far __pascal LibMain ( int a, short b, short c, long d )
#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS)
-#if 1 && defined(UA_GET32)
+#if 1 && defined(UA_GET_LE32)
#undef LZO_DICT_USE_PTR
#define LZO_DICT_USE_PTR 0
#undef lzo_dict_t
-#define lzo_dict_t unsigned short
+#define lzo_dict_t lzo_uint16_t
#endif
#define LZO_NEED_DICT_H 1
@@ -3086,81 +4606,7 @@ DVAL_ASSERT(lzo_xint dv, const lzo_bytep p)
#endif
#if 1 && defined(DO_COMPRESS) && !defined(do_compress)
-# define do_compress LZO_CPP_ECONCAT2(DO_COMPRESS,_core)
-#endif
-
-#if defined(UA_GET64) && (LZO_ABI_BIG_ENDIAN)
-# define WANT_lzo_bitops_clz64 1
-#elif defined(UA_GET64) && (LZO_ABI_LITTLE_ENDIAN)
-# define WANT_lzo_bitops_ctz64 1
-#elif defined(UA_GET32) && (LZO_ABI_BIG_ENDIAN)
-# define WANT_lzo_bitops_clz32 1
-#elif defined(UA_GET32) && (LZO_ABI_LITTLE_ENDIAN)
-# define WANT_lzo_bitops_ctz32 1
-#endif
-
-#if (defined(_WIN32) || defined(_WIN64)) && ((LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_MSC && (_MSC_VER >= 1400)))
-#include <intrin.h>
-#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32) && 0
-#pragma intrinsic(_BitScanReverse)
-static __lzo_inline unsigned lzo_bitops_clz32(lzo_uint32 v)
-{
- unsigned long r;
- (void) _BitScanReverse(&r, v);
- return (unsigned) r;
-}
-#define lzo_bitops_clz32 lzo_bitops_clz32
-#endif
-#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX) && 0
-#pragma intrinsic(_BitScanReverse64)
-static __lzo_inline unsigned lzo_bitops_clz64(lzo_uint64 v)
-{
- unsigned long r;
- (void) _BitScanReverse64(&r, v);
- return (unsigned) r;
-}
-#define lzo_bitops_clz64 lzo_bitops_clz64
-#endif
-#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32)
-#pragma intrinsic(_BitScanForward)
-static __lzo_inline unsigned lzo_bitops_ctz32(lzo_uint32 v)
-{
- unsigned long r;
- (void) _BitScanForward(&r, v);
- return (unsigned) r;
-}
-#define lzo_bitops_ctz32 lzo_bitops_ctz32
-#endif
-#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX)
-#pragma intrinsic(_BitScanForward64)
-static __lzo_inline unsigned lzo_bitops_ctz64(lzo_uint64 v)
-{
- unsigned long r;
- (void) _BitScanForward64(&r, v);
- return (unsigned) r;
-}
-#define lzo_bitops_ctz64 lzo_bitops_ctz64
-#endif
-
-#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_LLVM && (!defined(__llvm_tools_version__) || (__llvm_tools_version__+0 >= 0x010500ul))))
-#if !defined(lzo_bitops_clz32) && defined(WANT_lzo_bitops_clz32)
-#define lzo_bitops_clz32(v) ((unsigned) __builtin_clz(v))
-#endif
-#if !defined(lzo_bitops_clz64) && defined(WANT_lzo_bitops_clz64) && defined(LZO_UINT64_MAX)
-#define lzo_bitops_clz64(v) ((unsigned) __builtin_clzll(v))
-#endif
-#if !defined(lzo_bitops_ctz32) && defined(WANT_lzo_bitops_ctz32)
-#define lzo_bitops_ctz32(v) ((unsigned) __builtin_ctz(v))
-#endif
-#if !defined(lzo_bitops_ctz64) && defined(WANT_lzo_bitops_ctz64) && defined(LZO_UINT64_MAX)
-#define lzo_bitops_ctz64(v) ((unsigned) __builtin_ctzll(v))
-#endif
-#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount32)
-#define lzo_bitops_popcount32(v) ((unsigned) __builtin_popcount(v))
-#endif
-#if !defined(lzo_bitops_popcount32) && defined(WANT_lzo_bitops_popcount64) && defined(LZO_UINT64_MAX)
-#define lzo_bitops_popcount64(v) ((unsigned) __builtin_popcountll(v))
-#endif
+# define do_compress LZO_PP_ECONCAT2(DO_COMPRESS,_core)
#endif
static __lzo_noinline lzo_uint
@@ -3168,7 +4614,7 @@ do_compress ( const lzo_bytep in , lzo_uint in_len,
lzo_bytep out, lzo_uintp out_len,
lzo_uint ti, lzo_voidp wrkmem)
{
- register const lzo_bytep ip;
+ const lzo_bytep ip;
lzo_bytep op;
const lzo_bytep const in_end = in + in_len;
const lzo_bytep const ip_end = in + in_len - 20;
@@ -3207,8 +4653,8 @@ next:
goto literal;
try_match:
-#if defined(UA_GET32)
- if (UA_GET32(m_pos) != UA_GET32(ip))
+#if (LZO_OPT_UNALIGNED32)
+ if (UA_GET_NE32(m_pos) != UA_GET_NE32(ip))
#else
if (m_pos[0] != ip[0] || m_pos[1] != ip[1] || m_pos[2] != ip[2] || m_pos[3] != ip[3])
#endif
@@ -3223,50 +4669,43 @@ literal:
lzo_uint m_off;
lzo_uint m_len;
{
- lzo_uint32 dv;
+ lzo_uint32_t dv;
lzo_uint dindex;
literal:
ip += 1 + ((ip - ii) >> 5);
next:
if __lzo_unlikely(ip >= ip_end)
break;
- dv = UA_GET32(ip);
+ dv = UA_GET_LE32(ip);
dindex = DINDEX(dv,ip);
GINDEX(m_off,m_pos,in+dict,dindex,in);
UPDATE_I(dict,0,dindex,ip,in);
- if __lzo_unlikely(dv != UA_GET32(m_pos))
+ if __lzo_unlikely(dv != UA_GET_LE32(m_pos))
goto literal;
}
#endif
ii -= ti; ti = 0;
{
- register lzo_uint t = pd(ip,ii);
+ lzo_uint t = pd(ip,ii);
if (t != 0)
{
if (t <= 3)
{
- op[-2] |= LZO_BYTE(t);
-#if defined(UA_COPY32)
- UA_COPY32(op, ii);
+ op[-2] = LZO_BYTE(op[-2] | t);
+#if (LZO_OPT_UNALIGNED32)
+ UA_COPY4(op, ii);
op += t;
#else
{ do *op++ = *ii++; while (--t > 0); }
#endif
}
-#if defined(UA_COPY32) || defined(UA_COPY64)
+#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64)
else if (t <= 16)
{
*op++ = LZO_BYTE(t - 3);
-#if defined(UA_COPY64)
- UA_COPY64(op, ii);
- UA_COPY64(op+8, ii+8);
-#else
- UA_COPY32(op, ii);
- UA_COPY32(op+4, ii+4);
- UA_COPY32(op+8, ii+8);
- UA_COPY32(op+12, ii+12);
-#endif
+ UA_COPY8(op, ii);
+ UA_COPY8(op+8, ii+8);
op += t;
}
#endif
@@ -3276,31 +4715,21 @@ next:
*op++ = LZO_BYTE(t - 3);
else
{
- register lzo_uint tt = t - 18;
+ lzo_uint tt = t - 18;
*op++ = 0;
while __lzo_unlikely(tt > 255)
{
tt -= 255;
-#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400))
- * (volatile unsigned char *) op++ = 0;
-#else
- *op++ = 0;
-#endif
+ UA_SET1(op, 0);
+ op++;
}
assert(tt > 0);
*op++ = LZO_BYTE(tt);
}
-#if defined(UA_COPY32) || defined(UA_COPY64)
+#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64)
do {
-#if defined(UA_COPY64)
- UA_COPY64(op, ii);
- UA_COPY64(op+8, ii+8);
-#else
- UA_COPY32(op, ii);
- UA_COPY32(op+4, ii+4);
- UA_COPY32(op+8, ii+8);
- UA_COPY32(op+12, ii+12);
-#endif
+ UA_COPY8(op, ii);
+ UA_COPY8(op+8, ii+8);
op += 16; ii += 16; t -= 16;
} while (t >= 16); if (t > 0)
#endif
@@ -3310,26 +4739,26 @@ next:
}
m_len = 4;
{
-#if defined(UA_GET64)
- lzo_uint64 v;
- v = UA_GET64(ip + m_len) ^ UA_GET64(m_pos + m_len);
+#if (LZO_OPT_UNALIGNED64)
+ lzo_uint64_t v;
+ v = UA_GET_NE64(ip + m_len) ^ UA_GET_NE64(m_pos + m_len);
if __lzo_unlikely(v == 0) {
do {
m_len += 8;
- v = UA_GET64(ip + m_len) ^ UA_GET64(m_pos + m_len);
+ v = UA_GET_NE64(ip + m_len) ^ UA_GET_NE64(m_pos + m_len);
if __lzo_unlikely(ip + m_len >= ip_end)
goto m_len_done;
} while (v == 0);
}
-#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_clz64)
- m_len += lzo_bitops_clz64(v) / CHAR_BIT;
+#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_ctlz64)
+ m_len += lzo_bitops_ctlz64(v) / CHAR_BIT;
#elif (LZO_ABI_BIG_ENDIAN)
if ((v >> (64 - CHAR_BIT)) == 0) do {
v <<= CHAR_BIT;
m_len += 1;
} while ((v >> (64 - CHAR_BIT)) == 0);
-#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_ctz64)
- m_len += lzo_bitops_ctz64(v) / CHAR_BIT;
+#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_cttz64)
+ m_len += lzo_bitops_cttz64(v) / CHAR_BIT;
#elif (LZO_ABI_LITTLE_ENDIAN)
if ((v & UCHAR_MAX) == 0) do {
v >>= CHAR_BIT;
@@ -3340,26 +4769,30 @@ next:
m_len += 1;
} while (ip[m_len] == m_pos[m_len]);
#endif
-#elif defined(UA_GET32)
- lzo_uint32 v;
- v = UA_GET32(ip + m_len) ^ UA_GET32(m_pos + m_len);
+#elif (LZO_OPT_UNALIGNED32)
+ lzo_uint32_t v;
+ v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len);
if __lzo_unlikely(v == 0) {
do {
m_len += 4;
- v = UA_GET32(ip + m_len) ^ UA_GET32(m_pos + m_len);
+ v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len);
+ if (v != 0)
+ break;
+ m_len += 4;
+ v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len);
if __lzo_unlikely(ip + m_len >= ip_end)
goto m_len_done;
} while (v == 0);
}
-#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_clz32)
- m_len += lzo_bitops_clz32(v) / CHAR_BIT;
+#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_ctlz32)
+ m_len += lzo_bitops_ctlz32(v) / CHAR_BIT;
#elif (LZO_ABI_BIG_ENDIAN)
if ((v >> (32 - CHAR_BIT)) == 0) do {
v <<= CHAR_BIT;
m_len += 1;
} while ((v >> (32 - CHAR_BIT)) == 0);
-#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_ctz32)
- m_len += lzo_bitops_ctz32(v) / CHAR_BIT;
+#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_cttz32)
+ m_len += lzo_bitops_cttz32(v) / CHAR_BIT;
#elif (LZO_ABI_LITTLE_ENDIAN)
if ((v & UCHAR_MAX) == 0) do {
v >>= CHAR_BIT;
@@ -3374,6 +4807,27 @@ next:
if __lzo_unlikely(ip[m_len] == m_pos[m_len]) {
do {
m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
+ if (ip[m_len] != m_pos[m_len])
+ break;
+ m_len += 1;
if __lzo_unlikely(ip + m_len >= ip_end)
goto m_len_done;
} while (ip[m_len] == m_pos[m_len]);
@@ -3407,11 +4861,8 @@ m_len_done:
while __lzo_unlikely(m_len > 255)
{
m_len -= 255;
-#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400))
- * (volatile unsigned char *) op++ = 0;
-#else
- *op++ = 0;
-#endif
+ UA_SET1(op, 0);
+ op++;
}
*op++ = LZO_BYTE(m_len);
}
@@ -3430,11 +4881,8 @@ m_len_done:
while __lzo_unlikely(m_len > 255)
{
m_len -= 255;
-#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400))
- * (volatile unsigned char *) op++ = 0;
-#else
- *op++ = 0;
-#endif
+ UA_SET1(op, 0);
+ op++;
}
*op++ = LZO_BYTE(m_len);
}
@@ -3485,7 +4933,7 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
if (op == out && t <= 238)
*op++ = LZO_BYTE(17 + t);
else if (t <= 3)
- op[-2] |= LZO_BYTE(t);
+ op[-2] = LZO_BYTE(op[-2] | t);
else if (t <= 18)
*op++ = LZO_BYTE(t - 3);
else
@@ -3496,17 +4944,14 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
while (tt > 255)
{
tt -= 255;
-#if 1 && (LZO_CC_MSC && (_MSC_VER >= 1400))
-
- * (volatile unsigned char *) op++ = 0;
-#else
- *op++ = 0;
-#endif
+ UA_SET1(op, 0);
+ op++;
}
assert(tt > 0);
*op++ = LZO_BYTE(tt);
}
- do *op++ = *ii++; while (--t > 0);
+ UA_COPYN(op, ii, t);
+ op += t;
}
*op++ = M4_MARKER | 1;
@@ -3543,10 +4988,13 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
#undef TEST_IP
#undef TEST_OP
+#undef TEST_IP_AND_TEST_OP
#undef TEST_LB
#undef TEST_LBO
#undef NEED_IP
#undef NEED_OP
+#undef TEST_IV
+#undef TEST_OV
#undef HAVE_TEST_IP
#undef HAVE_TEST_OP
#undef HAVE_NEED_IP
@@ -3561,6 +5009,7 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
# if (LZO_TEST_OVERRUN_INPUT >= 2)
# define NEED_IP(x) \
if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun
# endif
#endif
@@ -3572,12 +5021,13 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
# undef TEST_OP
# define NEED_OP(x) \
if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun
# endif
#endif
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
-# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun
-# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun
+# define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun
+# define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun
#else
# define TEST_LB(m_pos) ((void) 0)
# define TEST_LBO(m_pos,o) ((void) 0)
@@ -3598,15 +5048,27 @@ DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len,
# define TEST_OP 1
#endif
+#if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP)
+# define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP)
+#elif defined(HAVE_TEST_IP)
+# define TEST_IP_AND_TEST_OP TEST_IP
+#elif defined(HAVE_TEST_OP)
+# define TEST_IP_AND_TEST_OP TEST_OP
+#else
+# define TEST_IP_AND_TEST_OP 1
+#endif
+
#if defined(NEED_IP)
# define HAVE_NEED_IP 1
#else
# define NEED_IP(x) ((void) 0)
+# define TEST_IV(x) ((void) 0)
#endif
#if defined(NEED_OP)
# define HAVE_NEED_OP 1
#else
# define NEED_OP(x) ((void) 0)
+# define TEST_OV(x) ((void) 0)
#endif
#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
@@ -3623,14 +5085,14 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
lzo_voidp wrkmem )
#endif
{
- register lzo_bytep op;
- register const lzo_bytep ip;
- register lzo_uint t;
+ lzo_bytep op;
+ const lzo_bytep ip;
+ lzo_uint t;
#if defined(COPY_DICT)
lzo_uint m_off;
const lzo_bytep dict_end;
#else
- register const lzo_bytep m_pos;
+ const lzo_bytep m_pos;
#endif
const lzo_bytep const ip_end = in + in_len;
@@ -3665,43 +5127,45 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
op = out;
ip = in;
+ NEED_IP(1);
if (*ip > 17)
{
t = *ip++ - 17;
if (t < 4)
goto match_next;
- assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ assert(t > 0); NEED_OP(t); NEED_IP(t+3);
do *op++ = *ip++; while (--t > 0);
goto first_literal_run;
}
- while (TEST_IP && TEST_OP)
+ for (;;)
{
+ NEED_IP(3);
t = *ip++;
if (t >= 16)
goto match;
if (t == 0)
{
- NEED_IP(1);
while (*ip == 0)
{
t += 255;
ip++;
+ TEST_IV(t);
NEED_IP(1);
}
t += 15 + *ip++;
}
- assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
-#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4)
+ assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
+#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
t += 3;
if (t >= 8) do
{
- UA_COPY64(op,ip);
+ UA_COPY8(op,ip);
op += 8; ip += 8; t -= 8;
} while (t >= 8);
if (t >= 4)
{
- UA_COPY32(op,ip);
+ UA_COPY4(op,ip);
op += 4; ip += 4; t -= 4;
}
if (t > 0)
@@ -3709,19 +5173,19 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
*op++ = *ip++;
if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
}
-#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
-#if !defined(LZO_UNALIGNED_OK_4)
+#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
+#if !(LZO_OPT_UNALIGNED32)
if (PTR_ALIGNED2_4(op,ip))
{
#endif
- UA_COPY32(op,ip);
+ UA_COPY4(op,ip);
op += 4; ip += 4;
if (--t > 0)
{
if (t >= 4)
{
do {
- UA_COPY32(op,ip);
+ UA_COPY4(op,ip);
op += 4; ip += 4; t -= 4;
} while (t >= 4);
if (t > 0) do *op++ = *ip++; while (--t > 0);
@@ -3729,12 +5193,12 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
else
do *op++ = *ip++; while (--t > 0);
}
-#if !defined(LZO_UNALIGNED_OK_4)
+#if !(LZO_OPT_UNALIGNED32)
}
else
#endif
#endif
-#if !defined(LZO_UNALIGNED_OK_4) && !defined(LZO_UNALIGNED_OK_8)
+#if !(LZO_OPT_UNALIGNED32)
{
*op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
do *op++ = *ip++; while (--t > 0);
@@ -3770,7 +5234,7 @@ first_literal_run:
#endif
goto match_done;
- do {
+ for (;;) {
match:
if (t >= 64)
{
@@ -3830,14 +5294,15 @@ match:
t &= 31;
if (t == 0)
{
- NEED_IP(1);
while (*ip == 0)
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 31 + *ip++;
+ NEED_IP(2);
}
#if defined(COPY_DICT)
#if defined(LZO1Z)
@@ -3853,9 +5318,9 @@ match:
m_pos = op - off;
last_m_off = off;
}
-#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
+#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
m_pos = op - 1;
- m_pos -= UA_GET16(ip) >> 2;
+ m_pos -= UA_GET_LE16(ip) >> 2;
#else
m_pos = op - 1;
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
@@ -3874,14 +5339,15 @@ match:
t &= 7;
if (t == 0)
{
- NEED_IP(1);
while (*ip == 0)
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 7 + *ip++;
+ NEED_IP(2);
}
#if defined(COPY_DICT)
#if defined(LZO1Z)
@@ -3899,8 +5365,8 @@ match:
#else
#if defined(LZO1Z)
m_pos -= (ip[0] << 6) + (ip[1] >> 2);
-#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
- m_pos -= UA_GET16(ip) >> 2;
+#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
+ m_pos -= UA_GET_LE16(ip) >> 2;
#else
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
#endif
@@ -3948,18 +5414,18 @@ match:
#else
TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
-#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4)
+#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
if (op - m_pos >= 8)
{
t += (3 - 1);
if (t >= 8) do
{
- UA_COPY64(op,m_pos);
+ UA_COPY8(op,m_pos);
op += 8; m_pos += 8; t -= 8;
} while (t >= 8);
if (t >= 4)
{
- UA_COPY32(op,m_pos);
+ UA_COPY4(op,m_pos);
op += 4; m_pos += 4; t -= 4;
}
if (t > 0)
@@ -3969,8 +5435,8 @@ match:
}
}
else
-#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
-#if !defined(LZO_UNALIGNED_OK_4)
+#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
+#if !(LZO_OPT_UNALIGNED32)
if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
{
assert((op - m_pos) >= 4);
@@ -3978,10 +5444,10 @@ match:
if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
{
#endif
- UA_COPY32(op,m_pos);
+ UA_COPY4(op,m_pos);
op += 4; m_pos += 4; t -= 4 - (3 - 1);
do {
- UA_COPY32(op,m_pos);
+ UA_COPY4(op,m_pos);
op += 4; m_pos += 4; t -= 4;
} while (t >= 4);
if (t > 0) do *op++ = *m_pos++; while (--t > 0);
@@ -4006,7 +5472,7 @@ match_done:
break;
match_next:
- assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1);
+ assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
#if 0
do *op++ = *ip++; while (--t > 0);
#else
@@ -4014,16 +5480,10 @@ match_next:
if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
#endif
t = *ip++;
- } while (TEST_IP && TEST_OP);
+ }
}
-#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
- *out_len = pd(op, out);
- return LZO_E_EOF_NOT_FOUND;
-#endif
-
eof_found:
- assert(t == 1);
*out_len = pd(op, out);
return (ip == ip_end ? LZO_E_OK :
(ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
@@ -4069,10 +5529,13 @@ lookbehind_overrun:
#undef TEST_IP
#undef TEST_OP
+#undef TEST_IP_AND_TEST_OP
#undef TEST_LB
#undef TEST_LBO
#undef NEED_IP
#undef NEED_OP
+#undef TEST_IV
+#undef TEST_OV
#undef HAVE_TEST_IP
#undef HAVE_TEST_OP
#undef HAVE_NEED_IP
@@ -4087,6 +5550,7 @@ lookbehind_overrun:
# if (LZO_TEST_OVERRUN_INPUT >= 2)
# define NEED_IP(x) \
if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun
+# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun
# endif
#endif
@@ -4098,12 +5562,13 @@ lookbehind_overrun:
# undef TEST_OP
# define NEED_OP(x) \
if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun
+# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun
# endif
#endif
#if defined(LZO_TEST_OVERRUN_LOOKBEHIND)
-# define TEST_LB(m_pos) if (m_pos < out || m_pos >= op) goto lookbehind_overrun
-# define TEST_LBO(m_pos,o) if (m_pos < out || m_pos >= op - (o)) goto lookbehind_overrun
+# define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun
+# define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun
#else
# define TEST_LB(m_pos) ((void) 0)
# define TEST_LBO(m_pos,o) ((void) 0)
@@ -4124,15 +5589,27 @@ lookbehind_overrun:
# define TEST_OP 1
#endif
+#if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP)
+# define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP)
+#elif defined(HAVE_TEST_IP)
+# define TEST_IP_AND_TEST_OP TEST_IP
+#elif defined(HAVE_TEST_OP)
+# define TEST_IP_AND_TEST_OP TEST_OP
+#else
+# define TEST_IP_AND_TEST_OP 1
+#endif
+
#if defined(NEED_IP)
# define HAVE_NEED_IP 1
#else
# define NEED_IP(x) ((void) 0)
+# define TEST_IV(x) ((void) 0)
#endif
#if defined(NEED_OP)
# define HAVE_NEED_OP 1
#else
# define NEED_OP(x) ((void) 0)
+# define TEST_OV(x) ((void) 0)
#endif
#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP)
@@ -4149,14 +5626,14 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
lzo_voidp wrkmem )
#endif
{
- register lzo_bytep op;
- register const lzo_bytep ip;
- register lzo_uint t;
+ lzo_bytep op;
+ const lzo_bytep ip;
+ lzo_uint t;
#if defined(COPY_DICT)
lzo_uint m_off;
const lzo_bytep dict_end;
#else
- register const lzo_bytep m_pos;
+ const lzo_bytep m_pos;
#endif
const lzo_bytep const ip_end = in + in_len;
@@ -4191,43 +5668,45 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
op = out;
ip = in;
+ NEED_IP(1);
if (*ip > 17)
{
t = *ip++ - 17;
if (t < 4)
goto match_next;
- assert(t > 0); NEED_OP(t); NEED_IP(t+1);
+ assert(t > 0); NEED_OP(t); NEED_IP(t+3);
do *op++ = *ip++; while (--t > 0);
goto first_literal_run;
}
- while (TEST_IP && TEST_OP)
+ for (;;)
{
+ NEED_IP(3);
t = *ip++;
if (t >= 16)
goto match;
if (t == 0)
{
- NEED_IP(1);
while (*ip == 0)
{
t += 255;
ip++;
+ TEST_IV(t);
NEED_IP(1);
}
t += 15 + *ip++;
}
- assert(t > 0); NEED_OP(t+3); NEED_IP(t+4);
-#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4)
+ assert(t > 0); NEED_OP(t+3); NEED_IP(t+6);
+#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
t += 3;
if (t >= 8) do
{
- UA_COPY64(op,ip);
+ UA_COPY8(op,ip);
op += 8; ip += 8; t -= 8;
} while (t >= 8);
if (t >= 4)
{
- UA_COPY32(op,ip);
+ UA_COPY4(op,ip);
op += 4; ip += 4; t -= 4;
}
if (t > 0)
@@ -4235,19 +5714,19 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
*op++ = *ip++;
if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
}
-#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
-#if !defined(LZO_UNALIGNED_OK_4)
+#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
+#if !(LZO_OPT_UNALIGNED32)
if (PTR_ALIGNED2_4(op,ip))
{
#endif
- UA_COPY32(op,ip);
+ UA_COPY4(op,ip);
op += 4; ip += 4;
if (--t > 0)
{
if (t >= 4)
{
do {
- UA_COPY32(op,ip);
+ UA_COPY4(op,ip);
op += 4; ip += 4; t -= 4;
} while (t >= 4);
if (t > 0) do *op++ = *ip++; while (--t > 0);
@@ -4255,12 +5734,12 @@ DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len,
else
do *op++ = *ip++; while (--t > 0);
}
-#if !defined(LZO_UNALIGNED_OK_4)
+#if !(LZO_OPT_UNALIGNED32)
}
else
#endif
#endif
-#if !defined(LZO_UNALIGNED_OK_4) && !defined(LZO_UNALIGNED_OK_8)
+#if !(LZO_OPT_UNALIGNED32)
{
*op++ = *ip++; *op++ = *ip++; *op++ = *ip++;
do *op++ = *ip++; while (--t > 0);
@@ -4296,7 +5775,7 @@ first_literal_run:
#endif
goto match_done;
- do {
+ for (;;) {
match:
if (t >= 64)
{
@@ -4356,14 +5835,15 @@ match:
t &= 31;
if (t == 0)
{
- NEED_IP(1);
while (*ip == 0)
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 31 + *ip++;
+ NEED_IP(2);
}
#if defined(COPY_DICT)
#if defined(LZO1Z)
@@ -4379,9 +5859,9 @@ match:
m_pos = op - off;
last_m_off = off;
}
-#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
+#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
m_pos = op - 1;
- m_pos -= UA_GET16(ip) >> 2;
+ m_pos -= UA_GET_LE16(ip) >> 2;
#else
m_pos = op - 1;
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
@@ -4400,14 +5880,15 @@ match:
t &= 7;
if (t == 0)
{
- NEED_IP(1);
while (*ip == 0)
{
t += 255;
ip++;
+ TEST_OV(t);
NEED_IP(1);
}
t += 7 + *ip++;
+ NEED_IP(2);
}
#if defined(COPY_DICT)
#if defined(LZO1Z)
@@ -4425,8 +5906,8 @@ match:
#else
#if defined(LZO1Z)
m_pos -= (ip[0] << 6) + (ip[1] >> 2);
-#elif defined(LZO_UNALIGNED_OK_2) && defined(LZO_ABI_LITTLE_ENDIAN)
- m_pos -= UA_GET16(ip) >> 2;
+#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN)
+ m_pos -= UA_GET_LE16(ip) >> 2;
#else
m_pos -= (ip[0] >> 2) + (ip[1] << 6);
#endif
@@ -4474,18 +5955,18 @@ match:
#else
TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1);
-#if defined(LZO_UNALIGNED_OK_8) && defined(LZO_UNALIGNED_OK_4)
+#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32)
if (op - m_pos >= 8)
{
t += (3 - 1);
if (t >= 8) do
{
- UA_COPY64(op,m_pos);
+ UA_COPY8(op,m_pos);
op += 8; m_pos += 8; t -= 8;
} while (t >= 8);
if (t >= 4)
{
- UA_COPY32(op,m_pos);
+ UA_COPY4(op,m_pos);
op += 4; m_pos += 4; t -= 4;
}
if (t > 0)
@@ -4495,8 +5976,8 @@ match:
}
}
else
-#elif defined(LZO_UNALIGNED_OK_4) || defined(LZO_ALIGNED_OK_4)
-#if !defined(LZO_UNALIGNED_OK_4)
+#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4)
+#if !(LZO_OPT_UNALIGNED32)
if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos))
{
assert((op - m_pos) >= 4);
@@ -4504,10 +5985,10 @@ match:
if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4)
{
#endif
- UA_COPY32(op,m_pos);
+ UA_COPY4(op,m_pos);
op += 4; m_pos += 4; t -= 4 - (3 - 1);
do {
- UA_COPY32(op,m_pos);
+ UA_COPY4(op,m_pos);
op += 4; m_pos += 4; t -= 4;
} while (t >= 4);
if (t > 0) do *op++ = *m_pos++; while (--t > 0);
@@ -4532,7 +6013,7 @@ match_done:
break;
match_next:
- assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+1);
+ assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3);
#if 0
do *op++ = *ip++; while (--t > 0);
#else
@@ -4540,16 +6021,10 @@ match_next:
if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } }
#endif
t = *ip++;
- } while (TEST_IP && TEST_OP);
+ }
}
-#if defined(HAVE_TEST_IP) || defined(HAVE_TEST_OP)
- *out_len = pd(op, out);
- return LZO_E_EOF_NOT_FOUND;
-#endif
-
eof_found:
- assert(t == 1);
*out_len = pd(op, out);
return (ip == ip_end ? LZO_E_OK :
(ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN));
@@ -4576,4 +6051,3 @@ lookbehind_overrun:
#endif
/***** End of minilzo.c *****/
-
diff --git a/extern/lzo/minilzo/minilzo.h b/extern/lzo/minilzo/minilzo.h
index f2c104856e3..79374546748 100644
--- a/extern/lzo/minilzo/minilzo.h
+++ b/extern/lzo/minilzo/minilzo.h
@@ -2,22 +2,7 @@
This file is part of the LZO real-time data compression library.
- Copyright (C) 2011 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2010 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2009 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2008 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2007 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2006 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2005 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2004 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2003 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2002 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2001 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 2000 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1999 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1998 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1997 Markus Franz Xaver Johannes Oberhumer
- Copyright (C) 1996 Markus Franz Xaver Johannes Oberhumer
+ Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer
All Rights Reserved.
The LZO library is free software; you can redistribute it and/or
@@ -50,7 +35,7 @@
#ifndef __MINILZO_H
#define __MINILZO_H 1
-#define MINILZO_VERSION 0x2060
+#define MINILZO_VERSION 0x2080
#ifdef __LZOCONF_H
# error "you cannot use both LZO and miniLZO"
@@ -78,7 +63,7 @@ extern "C" {
*/
#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS
-#define LZO1X_1_MEM_COMPRESS ((lzo_uint32) (16384L * lzo_sizeof_dict_t))
+#define LZO1X_1_MEM_COMPRESS ((lzo_uint32_t) (16384L * lzo_sizeof_dict_t))
#define LZO1X_MEM_DECOMPRESS (0)
@@ -101,11 +86,6 @@ lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len,
lzo_voidp wrkmem /* NOT USED */ );
-#define LZO_OUT_LEN(size) ((size) + (size) / 16 + 64 + 3)
-
-#define LZO_HEAP_ALLOC(var,size) \
- lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
-
#ifdef __cplusplus
} /* extern "C" */
#endif
diff --git a/intern/atomic/atomic_ops.h b/intern/atomic/atomic_ops.h
index 127552f8bd4..f63ff630c40 100644
--- a/intern/atomic/atomic_ops.h
+++ b/intern/atomic/atomic_ops.h
@@ -79,37 +79,57 @@
ATOMIC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
- return (__sync_add_and_fetch(p, x));
+ return __sync_add_and_fetch(p, x);
}
ATOMIC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
- return (__sync_sub_and_fetch(p, x));
+ return __sync_sub_and_fetch(p, x);
+}
+
+ATOMIC_INLINE uint64_t
+atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
+{
+ return __sync_val_compare_and_swap(v, old, _new);
}
#elif (defined(_MSC_VER))
ATOMIC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
- return (InterlockedExchangeAdd64(p, x));
+ return InterlockedExchangeAdd64(p, x);
}
ATOMIC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
- return (InterlockedExchangeAdd64(p, -((int64_t)x)));
+ return InterlockedExchangeAdd64(p, -((int64_t)x));
+}
+
+ATOMIC_INLINE uint64_t
+atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
+{
+ return InterlockedCompareExchange64((int64_t *)v, _new, old);
}
#elif (defined(__APPLE__))
ATOMIC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
- return (uint64_t)(OSAtomicAdd64((int64_t)x, (int64_t *)p));
+ return (uint64_t)OSAtomicAdd64((int64_t)x, (int64_t *)p);
}
ATOMIC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
- return (uint64_t)(OSAtomicAdd64(-((int64_t)x), (int64_t *)p));
+ return (uint64_t)OSAtomicAdd64(-((int64_t)x), (int64_t *)p);
+}
+
+ATOMIC_INLINE uint64_t
+atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
+{
+ uint64_t init_val = *v;
+ OSAtomicCompareAndSwap64((int64_t)old, (int64_t)_new, (int64_t *)v);
+ return init_val;
}
# elif (defined(__amd64__) || defined(__x86_64__))
ATOMIC_INLINE uint64_t
@@ -120,7 +140,7 @@ atomic_add_uint64(uint64_t *p, uint64_t x)
: "+r" (x), "=m" (*p) /* Outputs. */
: "m" (*p) /* Inputs. */
);
- return (x);
+ return x;
}
ATOMIC_INLINE uint64_t
@@ -132,8 +152,21 @@ atomic_sub_uint64(uint64_t *p, uint64_t x)
: "+r" (x), "=m" (*p) /* Outputs. */
: "m" (*p) /* Inputs. */
);
- return (x);
+ return x;
}
+
+ATOMIC_INLINE uint64_t
+atomic_cas_uint64(uint64_t *v, uint64_t old, uint64_t _new)
+{
+ uint64_t ret;
+ asm volatile (
+ "lock; cmpxchgq %2,%1"
+ : "=a" (ret), "+m" (*v)
+ : "r" (_new), "0" (old)
+ : "memory");
+ return ret;
+}
+
# elif (defined(JEMALLOC_ATOMIC9))
ATOMIC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
@@ -144,7 +177,7 @@ atomic_add_uint64(uint64_t *p, uint64_t x)
*/
assert(sizeof(uint64_t) == sizeof(unsigned long));
- return (atomic_fetchadd_long(p, (unsigned long)x) + x);
+ return atomic_fetchadd_long(p, (unsigned long)x) + x;
}
ATOMIC_INLINE uint64_t
@@ -152,19 +185,33 @@ atomic_sub_uint64(uint64_t *p, uint64_t x)
{
assert(sizeof(uint64_t) == sizeof(unsigned long));
- return (atomic_fetchadd_long(p, (unsigned long)(-(long)x)) - x);
+ return atomic_fetchadd_long(p, (unsigned long)(-(long)x)) - x;
+}
+
+ATOMIC_INLINE uint64_t
+atomic_cas_uint32(uint64_t *v, uint64_t old, uint64_t _new)
+{
+ assert(sizeof(uint64_t) == sizeof(unsigned long));
+
+ return atomic_cmpset_long(v, old, _new);
}
# elif (defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_8))
ATOMIC_INLINE uint64_t
atomic_add_uint64(uint64_t *p, uint64_t x)
{
- return (__sync_add_and_fetch(p, x));
+ return __sync_add_and_fetch(p, x);
}
ATOMIC_INLINE uint64_t
atomic_sub_uint64(uint64_t *p, uint64_t x)
{
- return (__sync_sub_and_fetch(p, x));
+ return __sync_sub_and_fetch(p, x);
+}
+
+ATOMIC_INLINE uint64_t
+atomic_cas_uint32(uint64_t *v, uint64_t old, uint64_t _new)
+{
+ return __sync_val_compare_and_swap(v, old, _new);
}
# else
# error "Missing implementation for 64-bit atomic operations"
@@ -177,37 +224,57 @@ atomic_sub_uint64(uint64_t *p, uint64_t x)
ATOMIC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
- return (__sync_add_and_fetch(p, x));
+ return __sync_add_and_fetch(p, x);
}
ATOMIC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
- return (__sync_sub_and_fetch(p, x));
+ return __sync_sub_and_fetch(p, x);
+}
+
+ATOMIC_INLINE uint32_t
+atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
+{
+ return __sync_val_compare_and_swap(v, old, _new);
}
#elif (defined(_MSC_VER))
ATOMIC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
- return (InterlockedExchangeAdd(p, x));
+ return InterlockedExchangeAdd(p, x);
}
ATOMIC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
- return (InterlockedExchangeAdd(p, -((int32_t)x)));
+ return InterlockedExchangeAdd(p, -((int32_t)x));
+}
+
+ATOMIC_INLINE uint32_t
+atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
+{
+ return InterlockedCompareExchange((long *)v, _new, old);
}
#elif (defined(__APPLE__))
ATOMIC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
- return (uint32_t)(OSAtomicAdd32((int32_t)x, (int32_t *)p));
+ return (uint32_t)OSAtomicAdd32((int32_t)x, (int32_t *)p);
}
ATOMIC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
- return (uint32_t)(OSAtomicAdd32(-((int32_t)x), (int32_t *)p));
+ return (uint32_t)OSAtomicAdd32(-((int32_t)x), (int32_t *)p);
+}
+
+ATOMIC_INLINE uint32_t
+atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
+{
+ uint32_t init_val = *v;
+ OSAtomicCompareAndSwap32((int32_t)old, (int32_t)_new, (int32_t *)v);
+ return init_val;
}
#elif (defined(__i386__) || defined(__amd64__) || defined(__x86_64__))
ATOMIC_INLINE uint32_t
@@ -218,7 +285,7 @@ atomic_add_uint32(uint32_t *p, uint32_t x)
: "+r" (x), "=m" (*p) /* Outputs. */
: "m" (*p) /* Inputs. */
);
- return (x);
+ return x;
}
ATOMIC_INLINE uint32_t
@@ -230,31 +297,55 @@ atomic_sub_uint32(uint32_t *p, uint32_t x)
: "+r" (x), "=m" (*p) /* Outputs. */
: "m" (*p) /* Inputs. */
);
- return (x);
+ return x;
+}
+
+ATOMIC_INLINE uint32_t
+atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
+{
+ uint32_t ret;
+ asm volatile (
+ "lock; cmpxchgl %2,%1"
+ : "=a" (ret), "+m" (*v)
+ : "r" (_new), "0" (old)
+ : "memory");
+ return ret;
}
#elif (defined(JEMALLOC_ATOMIC9))
ATOMIC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
- return (atomic_fetchadd_32(p, x) + x);
+ return atomic_fetchadd_32(p, x) + x;
}
ATOMIC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
- return (atomic_fetchadd_32(p, (uint32_t)(-(int32_t)x)) - x);
+ return atomic_fetchadd_32(p, (uint32_t)(-(int32_t)x)) - x;
}
-#elif (defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4))
+
+ATOMIC_INLINE uint32_t
+atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
+{
+ return atomic_cmpset_32(v, old, _new);
+}
+#elif defined(JE_FORCE_SYNC_COMPARE_AND_SWAP_4)
ATOMIC_INLINE uint32_t
atomic_add_uint32(uint32_t *p, uint32_t x)
{
- return (__sync_add_and_fetch(p, x));
+ return __sync_add_and_fetch(p, x);
}
ATOMIC_INLINE uint32_t
atomic_sub_uint32(uint32_t *p, uint32_t x)
{
- return (__sync_sub_and_fetch(p, x));
+ return __sync_sub_and_fetch(p, x);
+}
+
+ATOMIC_INLINE uint32_t
+atomic_cas_uint32(uint32_t *v, uint32_t old, uint32_t _new)
+{
+ return __sync_val_compare_and_swap(v, old, _new);
}
#else
# error "Missing implementation for 32-bit atomic operations"
@@ -268,9 +359,9 @@ atomic_add_z(size_t *p, size_t x)
assert(sizeof(size_t) == 1 << LG_SIZEOF_PTR);
#if (LG_SIZEOF_PTR == 3)
- return ((size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)x));
+ return (size_t)atomic_add_uint64((uint64_t *)p, (uint64_t)x);
#elif (LG_SIZEOF_PTR == 2)
- return ((size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)x));
+ return (size_t)atomic_add_uint32((uint32_t *)p, (uint32_t)x);
#endif
}
@@ -280,11 +371,27 @@ atomic_sub_z(size_t *p, size_t x)
assert(sizeof(size_t) == 1 << LG_SIZEOF_PTR);
#if (LG_SIZEOF_PTR == 3)
- return ((size_t)atomic_add_uint64((uint64_t *)p,
- (uint64_t)-((int64_t)x)));
+ return (size_t)atomic_add_uint64((uint64_t *)p,
+ (uint64_t)-((int64_t)x));
#elif (LG_SIZEOF_PTR == 2)
- return ((size_t)atomic_add_uint32((uint32_t *)p,
- (uint32_t)-((int32_t)x)));
+ return (size_t)atomic_add_uint32((uint32_t *)p,
+ (uint32_t)-((int32_t)x));
+#endif
+}
+
+ATOMIC_INLINE size_t
+atomic_cas_z(size_t *v, size_t old, size_t _new)
+{
+ assert(sizeof(size_t) == 1 << LG_SIZEOF_PTR);
+
+#if (LG_SIZEOF_PTR == 3)
+ return (size_t)atomic_cas_uint64((uint64_t *)v,
+ (uint64_t)old,
+ (uint64_t)_new);
+#elif (LG_SIZEOF_PTR == 2)
+ return (size_t)atomic_cas_uint32((uint32_t *)v,
+ (uint32_t)old,
+ (uint32_t)_new);
#endif
}
@@ -296,9 +403,9 @@ atomic_add_u(unsigned *p, unsigned x)
assert(sizeof(unsigned) == 1 << LG_SIZEOF_INT);
#if (LG_SIZEOF_INT == 3)
- return ((unsigned)atomic_add_uint64((uint64_t *)p, (uint64_t)x));
+ return (unsigned)atomic_add_uint64((uint64_t *)p, (uint64_t)x);
#elif (LG_SIZEOF_INT == 2)
- return ((unsigned)atomic_add_uint32((uint32_t *)p, (uint32_t)x));
+ return (unsigned)atomic_add_uint32((uint32_t *)p, (uint32_t)x);
#endif
}
@@ -308,11 +415,27 @@ atomic_sub_u(unsigned *p, unsigned x)
assert(sizeof(unsigned) == 1 << LG_SIZEOF_INT);
#if (LG_SIZEOF_INT == 3)
- return ((unsigned)atomic_add_uint64((uint64_t *)p,
- (uint64_t)-((int64_t)x)));
+ return (unsigned)atomic_add_uint64((uint64_t *)p,
+ (uint64_t)-((int64_t)x));
#elif (LG_SIZEOF_INT == 2)
- return ((unsigned)atomic_add_uint32((uint32_t *)p,
- (uint32_t)-((int32_t)x)));
+ return (unsigned)atomic_add_uint32((uint32_t *)p,
+ (uint32_t)-((int32_t)x));
+#endif
+}
+
+ATOMIC_INLINE unsigned
+atomic_cas_u(unsigned *v, unsigned old, unsigned _new)
+{
+ assert(sizeof(unsigned) == 1 << LG_SIZEOF_INT);
+
+#if (LG_SIZEOF_PTR == 3)
+ return (unsigned)atomic_cas_uint64((uint64_t *)v,
+ (uint64_t)old,
+ (uint64_t)_new);
+#elif (LG_SIZEOF_PTR == 2)
+ return (unsigned)atomic_cas_uint32((uint32_t *)v,
+ (uint32_t)old,
+ (uint32_t)_new);
#endif
}
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index ccf6aac945e..981499b3a91 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -128,6 +128,30 @@ add_definitions(
-DWITH_MULTI
)
+# Logging capabilities using GLog library.
+if(WITH_CYCLES_LOGGING)
+ add_definitions(-DWITH_CYCLES_LOGGING)
+ add_definitions(-DGOOGLE_GLOG_DLL_DECL=)
+ if(WIN32)
+ include_directories(
+ SYSTEM
+ ../../extern/libmv/third_party/glog/src/windows
+ ../../extern/libmv/third_party/gflags
+ )
+ else()
+ include_directories(
+ SYSTEM
+ ../../extern/libmv/third_party/glog/src
+ ../../extern/libmv/third_party/gflags
+ )
+ endif()
+endif()
+
+# Debugging capabilities (debug passes etc).
+if(WITH_CYCLES_DEBUG)
+ add_definitions(-DWITH_CYCLES_DEBUG)
+endif()
+
include_directories(
SYSTEM
${BOOST_INCLUDE_DIR}
diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript
index 2d7fbe9c593..b399844534d 100644
--- a/intern/cycles/SConscript
+++ b/intern/cycles/SConscript
@@ -59,6 +59,9 @@ if env['WITH_BF_CYCLES_OSL']:
defs.append('OSL_STATIC_LIBRARY')
incs.append(cycles['BF_OSL_INC'])
+if env['WITH_BF_CYCLES_DEBUG']:
+ defs.append('WITH_CYCLES_DEBUG')
+
incs.extend('. bvh render device kernel kernel/osl kernel/svm util subd'.split())
incs.extend('#intern/guardedalloc #source/blender/makesrna #source/blender/makesdna #source/blender/blenlib'.split())
incs.extend('#source/blender/blenloader ../../source/blender/makesrna/intern'.split())
diff --git a/intern/cycles/app/io_export_cycles_xml.py b/intern/cycles/app/io_export_cycles_xml.py
index e310d928b26..ad8fb9d3dd3 100644
--- a/intern/cycles/app/io_export_cycles_xml.py
+++ b/intern/cycles/app/io_export_cycles_xml.py
@@ -111,19 +111,29 @@ class ExportCyclesXML(bpy.types.Operator, ExportHelper):
# generate mesh node
nverts = ""
verts = ""
+ uvs = ""
P = ""
for v in mesh.vertices:
P += "%f %f %f " % (v.co[0], v.co[1], v.co[2])
- for i, f in enumerate(mesh.tessfaces):
- nverts += str(len(f.vertices)) + " "
+ verts_and_uvs = zip(mesh.tessfaces, mesh.tessface_uv_textures.active.data)
+
+ for f, uvf in verts_and_uvs:
+ vcount = len(f.vertices)
+ nverts += str(vcount) + " "
for v in f.vertices:
verts += str(v) + " "
- verts += " "
-
- node = etree.Element('mesh', attrib={'nverts': nverts, 'verts': verts, 'P': P})
+
+ uvs += str(uvf.uv1[0]) + " " + str(uvf.uv1[1]) + " "
+ uvs += str(uvf.uv2[0]) + " " + str(uvf.uv2[1]) + " "
+ uvs += str(uvf.uv3[0]) + " " + str(uvf.uv3[1]) + " "
+ if vcount==4:
+ uvs += " " + str(uvf.uv4[0]) + " " + str(uvf.uv4[1]) + " "
+
+
+ node = etree.Element('mesh', attrib={'nverts': nverts.strip(), 'verts': verts.strip(), 'P': P, 'UV' : uvs.strip()})
# write to file
write(node, filepath)
@@ -139,3 +149,4 @@ def unregister():
if __name__ == "__main__":
register()
+
diff --git a/intern/cycles/blender/CCL_api.h b/intern/cycles/blender/CCL_api.h
index 2772b9ac8a7..cfd0c3ef264 100644
--- a/intern/cycles/blender/CCL_api.h
+++ b/intern/cycles/blender/CCL_api.h
@@ -36,6 +36,10 @@ CCLDeviceInfo *CCL_compute_device_list(int device_type);
void *CCL_python_module_init(void);
+void CCL_init_logging(const char *argv0);
+void CCL_start_debug_logging(void);
+void CCL_logging_verbosity_set(int verbosity);
+
#ifdef __cplusplus
}
#endif
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index e97ad2e71f5..e1d592d32b4 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -26,6 +26,7 @@ set(SRC
blender_object.cpp
blender_particles.cpp
blender_curves.cpp
+ blender_logging.cpp
blender_python.cpp
blender_session.cpp
blender_shader.cpp
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index d1d27df8dc3..8c60ea31053 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -33,6 +33,7 @@ import bpy
from . import engine
from . import version_update
+
class CyclesRender(bpy.types.RenderEngine):
bl_idname = 'CYCLES'
bl_label = "Cycles Render"
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 0ac0e0f091e..597ac1a9ce0 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -37,7 +37,7 @@ if _cycles.with_network:
enum_feature_set = (
('SUPPORTED', "Supported", "Only use finished and supported features"),
- ('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future"),
+ ('EXPERIMENTAL', "Experimental", "Use experimental and incomplete features that might be broken or change in the future", 'ERROR', 1),
)
enum_displacement_methods = (
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 6e40c42fb2d..9632b12c414 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -567,7 +567,7 @@ class CyclesObject_PT_motion_blur(CyclesButtonsPanel, Panel):
layout = self.layout
rd = context.scene.render
- scene = context.scene
+ # scene = context.scene
layout.active = rd.use_motion_blur
@@ -580,7 +580,7 @@ class CyclesObject_PT_motion_blur(CyclesButtonsPanel, Panel):
layout = self.layout
rd = context.scene.render
- scene = context.scene
+ # scene = context.scene
ob = context.object
cob = ob.cycles
@@ -982,7 +982,7 @@ class CyclesMaterial_PT_volume(CyclesButtonsPanel, Panel):
layout = self.layout
mat = context.material
- cmat = mat.cycles
+ # cmat = mat.cycles
panel_node_draw(layout, mat, 'OUTPUT_MATERIAL', 'Volume')
@@ -1209,7 +1209,6 @@ class CyclesRender_PT_CurveRendering(CyclesButtonsPanel, Panel):
@classmethod
def poll(cls, context):
- scene = context.scene
psys = context.particle_system
return CyclesButtonsPanel.poll(context) and psys and psys.settings.type == 'HAIR'
@@ -1284,7 +1283,7 @@ class CyclesRender_PT_bake(CyclesButtonsPanel, Panel):
box.prop(cbk, "normal_space", text="Space")
row = box.row(align=True)
- row.label(text = "Swizzle:")
+ row.label(text="Swizzle:")
row.prop(cbk, "normal_r", text="")
row.prop(cbk, "normal_g", text="")
row.prop(cbk, "normal_b", text="")
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index 6f9509e7d99..eaeec703ff5 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -28,17 +28,32 @@ def do_versions(self):
if not bpy.data.is_saved:
return
+ # Clamp Direct/Indirect separation in 270
+ if bpy.data.version <= (2, 70, 0):
+ for scene in bpy.data.scenes:
+ cscene = scene.cycles
+ sample_clamp = cscene.get("sample_clamp", False)
+ if (sample_clamp and
+ not cscene.is_property_set("sample_clamp_direct") and
+ not cscene.is_property_set("sample_clamp_indirect")):
+
+ cscene.sample_clamp_direct = sample_clamp
+ cscene.sample_clamp_indirect = sample_clamp
+
+ # Change of Volume Bounces in 271
if bpy.data.version <= (2, 71, 0):
for scene in bpy.data.scenes:
cscene = scene.cycles
if not cscene.is_property_set("volume_bounces"):
cscene.volume_bounces = 1
- for scene in bpy.data.scenes:
- cscene = scene.cycles
- if (cscene.get("no_caustics", False) and
- not cscene.is_property_set("caustics_reflective") and
- not cscene.is_property_set("caustics_refractive")):
+ # Caustics Reflective/Refractive separation in 272
+ if bpy.data.version <= (2, 72, 0):
+ for scene in bpy.data.scenes:
+ cscene = scene.cycles
+ if (cscene.get("no_caustics", False) and
+ not cscene.is_property_set("caustics_reflective") and
+ not cscene.is_property_set("caustics_refractive")):
- cscene.caustics_reflective = False
- cscene.caustics_refractive = False
+ cscene.caustics_reflective = False
+ cscene.caustics_refractive = False
diff --git a/intern/cycles/blender/blender_logging.cpp b/intern/cycles/blender/blender_logging.cpp
new file mode 100644
index 00000000000..d3f1accf099
--- /dev/null
+++ b/intern/cycles/blender/blender_logging.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2011-2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#include "CCL_api.h"
+
+#include <stdio.h>
+
+#include "util_logging.h"
+
+#ifdef _MSC_VER
+# define snprintf _snprintf
+#endif
+
+void CCL_init_logging(const char *argv0)
+{
+#ifdef WITH_CYCLES_LOGGING
+ /* Make it so FATAL messages are always print into console. */
+ char severity_fatal[32];
+ snprintf(severity_fatal, sizeof(severity_fatal), "%d",
+ google::GLOG_FATAL);
+
+ google::InitGoogleLogging(argv0);
+ google::SetCommandLineOption("logtostderr", "1");
+ google::SetCommandLineOption("v", "0");
+ google::SetCommandLineOption("stderrthreshold", severity_fatal);
+ google::SetCommandLineOption("minloglevel", severity_fatal);
+#else
+ (void) argv0;
+#endif
+}
+
+void CCL_start_debug_logging(void)
+{
+#ifdef WITH_CYCLES_LOGGING
+ google::SetCommandLineOption("logtostderr", "1");
+ google::SetCommandLineOption("v", "2");
+ google::SetCommandLineOption("stderrthreshold", "1");
+ google::SetCommandLineOption("minloglevel", "0");
+#endif
+}
+
+void CCL_logging_verbosity_set(int verbosity)
+{
+#ifdef WITH_CYCLES_LOGGING
+ char val[10];
+ snprintf(val, sizeof(val), "%d", verbosity);
+
+ google::SetCommandLineOption("v", val);
+#else
+ (void) verbosity;
+#endif
+}
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 4ff3d89f9f1..0610c3f6579 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -261,6 +261,14 @@ static PassType get_pass_type(BL::RenderPass b_pass)
case BL::RenderPass::type_SPECULAR:
case BL::RenderPass::type_REFLECTION:
return PASS_NONE;
+#ifdef WITH_CYCLES_DEBUG
+ case BL::RenderPass::type_DEBUG:
+ {
+ if(b_pass.debug_type() == BL::RenderPass::debug_type_BVH_TRAVERSAL_STEPS)
+ return PASS_BVH_TRAVERSAL_STEPS;
+ break;
+ }
+#endif
}
return PASS_NONE;
@@ -423,6 +431,9 @@ void BlenderSession::render()
/* add passes */
vector<Pass> passes;
Pass::add(PASS_COMBINED, passes);
+#ifdef WITH_CYCLES_DEBUG
+ Pass::add(PASS_BVH_TRAVERSAL_STEPS, passes);
+#endif
if(session_params.device.advanced_shading) {
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index 7752c1ce1bd..33c7bf5f859 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -53,13 +53,13 @@ void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default
static BL::NodeSocket get_node_output(BL::Node b_node, const string& name)
{
BL::Node::outputs_iterator b_out;
-
+
for(b_node.outputs.begin(b_out); b_out != b_node.outputs.end(); ++b_out)
if(b_out->name() == name)
return *b_out;
-
+
assert(0);
-
+
return *b_out;
}
@@ -229,7 +229,11 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::ShaderNodeMixRGB b_mix_node(b_node);
MixNode *mix = new MixNode();
mix->type = MixNode::type_enum[b_mix_node.blend_type()];
- mix->use_clamp = b_mix_node.use_clamp();
+ /* Tag if it's Mix */
+ if(b_mix_node.blend_type() == 0)
+ mix->special_type = SHADER_SPECIAL_TYPE_MIX_RGB;
+
+ mix->use_clamp = b_mix_node.use_clamp();
node = mix;
}
else if (b_node.is_a(&RNA_ShaderNodeSeparateRGB)) {
@@ -260,7 +264,7 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
BL::ShaderNodeMath b_math_node(b_node);
MathNode *math = new MathNode();
math->type = MathNode::type_enum[b_math_node.operation()];
- math->use_clamp = b_math_node.use_clamp();
+ math->use_clamp = b_math_node.use_clamp();
node = math;
}
else if (b_node.is_a(&RNA_ShaderNodeVectorMath)) {
@@ -280,7 +284,7 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
else if (b_node.is_a(&RNA_ShaderNodeNormal)) {
BL::Node::outputs_iterator out_it;
b_node.outputs.begin(out_it);
-
+
NormalNode *norm = new NormalNode();
norm->direction = get_node_output_vector(b_node, "Normal");
node = norm;
@@ -288,9 +292,9 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
else if (b_node.is_a(&RNA_ShaderNodeMapping)) {
BL::ShaderNodeMapping b_mapping_node(b_node);
MappingNode *mapping = new MappingNode();
-
+
get_tex_mapping(&mapping->tex_mapping, b_mapping_node);
-
+
node = mapping;
}
else if (b_node.is_a(&RNA_ShaderNodeFresnel)) {
@@ -496,7 +500,7 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
/* create script node */
BL::ShaderNodeScript b_script_node(b_node);
OSLScriptNode *script_node = new OSLScriptNode();
-
+
/* Generate inputs/outputs from node sockets
*
* Note: the node sockets are generated from OSL parameters,
@@ -505,38 +509,38 @@ static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scen
* Note 2: ShaderInput/ShaderOutput store shallow string copies only!
* Socket names must be stored in the extra lists instead. */
BL::Node::inputs_iterator b_input;
-
+
for (b_script_node.inputs.begin(b_input); b_input != b_script_node.inputs.end(); ++b_input) {
script_node->input_names.push_back(ustring(b_input->name()));
ShaderInput *input = script_node->add_input(script_node->input_names.back().c_str(),
convert_socket_type(*b_input));
set_default_value(input, b_node, *b_input, b_data, b_ntree);
}
-
+
BL::Node::outputs_iterator b_output;
-
+
for (b_script_node.outputs.begin(b_output); b_output != b_script_node.outputs.end(); ++b_output) {
script_node->output_names.push_back(ustring(b_output->name()));
script_node->add_output(script_node->output_names.back().c_str(),
convert_socket_type(*b_output));
}
-
+
/* load bytecode or filepath */
OSLShaderManager *manager = (OSLShaderManager*)scene->shader_manager;
string bytecode_hash = b_script_node.bytecode_hash();
-
+
if(!bytecode_hash.empty()) {
/* loaded bytecode if not already done */
if(!manager->shader_test_loaded(bytecode_hash))
manager->shader_load_bytecode(bytecode_hash, b_script_node.bytecode());
-
+
script_node->bytecode_hash = bytecode_hash;
}
else {
/* set filepath */
script_node->filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath());
}
-
+
node = script_node;
}
#endif
@@ -728,7 +732,7 @@ static bool node_use_modified_socket_name(ShaderNode *node)
{
if (node->special_type == SHADER_SPECIAL_TYPE_SCRIPT)
return false;
-
+
return true;
}
@@ -740,57 +744,57 @@ static ShaderInput *node_find_input_by_name(ShaderNode *node, BL::Node b_node, B
BL::Node::inputs_iterator b_input;
bool found = false;
int counter = 0, total = 0;
-
+
for (b_node.inputs.begin(b_input); b_input != b_node.inputs.end(); ++b_input) {
if (b_input->name() == name) {
if (!found)
counter++;
total++;
}
-
+
if(b_input->ptr.data == b_socket.ptr.data)
found = true;
}
-
+
/* rename if needed */
if (name == "Shader")
name = "Closure";
-
+
if (total > 1)
name = string_printf("%s%d", name.c_str(), counter);
}
-
+
return node->input(name.c_str());
}
static ShaderOutput *node_find_output_by_name(ShaderNode *node, BL::Node b_node, BL::NodeSocket b_socket)
{
string name = b_socket.name();
-
+
if (node_use_modified_socket_name(node)) {
BL::Node::outputs_iterator b_output;
bool found = false;
int counter = 0, total = 0;
-
+
for (b_node.outputs.begin(b_output); b_output != b_node.outputs.end(); ++b_output) {
if (b_output->name() == name) {
if (!found)
counter++;
total++;
}
-
+
if(b_output->ptr.data == b_socket.ptr.data)
found = true;
}
-
+
/* rename if needed */
if (name == "Shader")
name = "Closure";
-
+
if (total > 1)
name = string_printf("%s%d", name.c_str(), counter);
}
-
+
return node->output(name.c_str());
}
@@ -801,7 +805,7 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
BL::ShaderNodeTree::nodes_iterator b_node;
PtrInputMap input_map;
PtrOutputMap output_map;
-
+
BL::Node::inputs_iterator b_input;
BL::Node::outputs_iterator b_output;
@@ -831,10 +835,10 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
BL::Node::internal_links_iterator b_link;
for (b_node->internal_links.begin(b_link); b_link != b_node->internal_links.end(); ++b_link) {
ProxyNode *proxy = new ProxyNode(convert_socket_type(b_link->to_socket()));
-
+
input_map[b_link->from_socket().ptr.data] = proxy->inputs[0];
output_map[b_link->to_socket().ptr.data] = proxy->outputs[0];
-
+
graph->add(proxy);
}
}
@@ -846,7 +850,7 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
else
b_group_ntree = BL::ShaderNodeTree(((BL::NodeCustomGroup)(*b_node)).node_tree());
ProxyMap group_proxy_input_map, group_proxy_output_map;
-
+
/* Add a proxy node for each socket
* Do this even if the node group has no internal tree,
* so that links have something to connect to and assert won't fail.
@@ -854,21 +858,21 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
ProxyNode *proxy = new ProxyNode(convert_socket_type(*b_input));
graph->add(proxy);
-
+
/* register the proxy node for internal binding */
group_proxy_input_map[b_input->identifier()] = proxy;
-
+
input_map[b_input->ptr.data] = proxy->inputs[0];
-
+
set_default_value(proxy->inputs[0], *b_node, *b_input, b_data, b_ntree);
}
for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
ProxyNode *proxy = new ProxyNode(convert_socket_type(*b_output));
graph->add(proxy);
-
+
/* register the proxy node for internal binding */
group_proxy_output_map[b_output->identifier()] = proxy;
-
+
output_map[b_output->ptr.data] = proxy->outputs[0];
}
@@ -881,7 +885,7 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
ProxyMap::const_iterator proxy_it = proxy_input_map.find(b_output->identifier());
if (proxy_it != proxy_input_map.end()) {
ProxyNode *proxy = proxy_it->second;
-
+
output_map[b_output->ptr.data] = proxy->outputs[0];
}
}
@@ -895,9 +899,9 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
ProxyMap::const_iterator proxy_it = proxy_output_map.find(b_input->identifier());
if (proxy_it != proxy_output_map.end()) {
ProxyNode *proxy = proxy_it->second;
-
+
input_map[b_input->ptr.data] = proxy->inputs[0];
-
+
set_default_value(proxy->inputs[0], *b_node, *b_input, b_data, b_ntree);
}
}
@@ -914,7 +918,7 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
else {
node = add_node(scene, b_data, b_scene, graph, b_ntree, BL::ShaderNode(*b_node));
}
-
+
if(node) {
/* map node sockets for linking */
for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
@@ -924,7 +928,7 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
continue;
}
input_map[b_input->ptr.data] = input;
-
+
set_default_value(input, *b_node, *b_input, b_data, b_ntree);
}
for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
@@ -949,7 +953,7 @@ static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, Sha
ShaderOutput *output = 0;
ShaderInput *input = 0;
-
+
PtrOutputMap::iterator output_it = output_map.find(b_from_sock.ptr.data);
if (output_it != output_map.end())
output = output_it->second;
@@ -981,7 +985,7 @@ void BlenderSync::sync_materials(bool update_all)
for(b_data.materials.begin(b_mat); b_mat != b_data.materials.end(); ++b_mat) {
Shader *shader;
-
+
/* test if we need to sync */
if(shader_map.sync(&shader, *b_mat) || update_all) {
ShaderGraph *graph = new ShaderGraph();
@@ -1036,7 +1040,7 @@ void BlenderSync::sync_world(bool update_all)
BL::ShaderNodeTree b_ntree(b_world.node_tree());
add_nodes(scene, b_data, b_scene, graph, b_ntree);
-
+
/* volume */
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
shader->heterogeneous_volume = !get_boolean(cworld, "homogeneous_volume");
@@ -1109,7 +1113,7 @@ void BlenderSync::sync_lamps(bool update_all)
for(b_data.lamps.begin(b_lamp); b_lamp != b_data.lamps.end(); ++b_lamp) {
Shader *shader;
-
+
/* test if we need to sync */
if(shader_map.sync(&shader, *b_lamp) || update_all) {
ShaderGraph *graph = new ShaderGraph();
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 4623764d210..c9b8a5b726b 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -17,6 +17,11 @@
#include <stdlib.h>
#include <string.h>
+/* So ImathMath is included before our kernel_cpu_compat. */
+#ifdef WITH_OSL
+# include <OSL/oslexec.h>
+#endif
+
#include "device.h"
#include "device_intern.h"
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 5de2efab8be..44be7779891 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -202,6 +202,10 @@ public:
/* compute cubin name */
int major, minor;
cuDeviceComputeCapability(&major, &minor, cuDevId);
+
+ /* workaround to make sm_52 cards work, until we bundle kernel */
+ if(major == 5 && minor == 2)
+ minor = 0;
/* attempt to use kernel provided with blender */
string cubin;
@@ -274,6 +278,10 @@ public:
if(experimental)
command += " -D__KERNEL_CUDA_EXPERIMENTAL__";
+#ifdef WITH_CYCLES_DEBUG
+ command += " -D__KERNEL_DEBUG__";
+#endif
+
printf("%s\n", command.c_str());
if(system(command.c_str()) == -1) {
diff --git a/intern/cycles/device/device_memory.h b/intern/cycles/device/device_memory.h
index 8eee6a2c79e..07a6eb36a3c 100644
--- a/intern/cycles/device/device_memory.h
+++ b/intern/cycles/device/device_memory.h
@@ -260,6 +260,11 @@ public:
return data.size();
}
+ T* get_data()
+ {
+ return &data[0];
+ }
+
private:
array<T> data;
};
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index d950d084cd4..58b2bcafb82 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -102,7 +102,11 @@ static string opencl_kernel_build_options(const string& platform, const string *
if(opencl_kernel_use_debug())
build_options += "-D__KERNEL_OPENCL_DEBUG__ ";
-
+
+#ifdef WITH_CYCLES_DEBUG
+ build_options += "-D__KERNEL_DEBUG__ ";
+#endif
+
return build_options;
}
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 8857f86890c..c521e1383a4 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -24,6 +24,7 @@ set(SRC_HEADERS
kernel_compat_cpu.h
kernel_compat_cuda.h
kernel_compat_opencl.h
+ kernel_debug.h
kernel_differential.h
kernel_emission.h
kernel_film.h
@@ -61,7 +62,6 @@ set(SRC_CLOSURE_HEADERS
closure/bsdf_transparent.h
closure/bsdf_util.h
closure/bsdf_ashikhmin_shirley.h
- closure/bsdf_westin.h
closure/bsdf_hair.h
closure/bssrdf.h
closure/emissive.h
@@ -116,6 +116,7 @@ set(SRC_GEOM_HEADERS
geom/geom_bvh_shadow.h
geom/geom_bvh_subsurface.h
geom/geom_bvh_traversal.h
+ geom/geom_bvh_volume.h
geom/geom_curve.h
geom/geom_motion_curve.h
geom/geom_motion_triangle.h
@@ -169,6 +170,12 @@ if(WITH_CYCLES_CUDA_BINARIES)
set(cuda_cubin kernel_${arch}.cubin)
endif()
+ if(WITH_CYCLES_DEBUG)
+ set(cuda_debug_flags "-D__KERNEL_DEBUG__")
+ else()
+ set(cuda_debug_flags "")
+ endif()
+
set(cuda_version_flags "-D__KERNEL_CUDA_VERSION__=${CUDA_VERSION}")
set(cuda_math_flags "--use_fast_math")
@@ -184,6 +191,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
${cuda_version_flags}
${cuda_math_flags}
${cuda_extra_flags}
+ ${cuda_debug_flags}
-I${CMAKE_CURRENT_SOURCE_DIR}/../util
-I${CMAKE_CURRENT_SOURCE_DIR}/svm
-DCCL_NAMESPACE_BEGIN=
@@ -196,6 +204,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
list(APPEND cuda_cubins ${cuda_cubin})
unset(cuda_extra_flags)
+ unset(cuda_debug_flags)
endmacro()
foreach(arch ${CYCLES_CUDA_BINARIES_ARCH})
diff --git a/intern/cycles/kernel/SConscript b/intern/cycles/kernel/SConscript
index 5a9e57c5342..c0d969e24ae 100644
--- a/intern/cycles/kernel/SConscript
+++ b/intern/cycles/kernel/SConscript
@@ -79,6 +79,9 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
nvcc_flags += " -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC"
nvcc_flags += " -I \"%s\" -I \"%s\" -I \"%s\" -I \"%s\"" % (util_dir, svm_dir, geom_dir, closure_dir)
+ if env['WITH_BF_CYCLES_DEBUG']:
+ nvcc_flags += " -D__KERNEL_DEBUG__"
+
# dependencies
dependencies = ['kernel.cu'] + kernel.Glob('*.h') + kernel.Glob('../util/*.h') + kernel.Glob('svm/*.h') + kernel.Glob('geom/*.h') + kernel.Glob('closure/*.h')
last_cubin_file = None
diff --git a/intern/cycles/kernel/closure/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index 9961071c2ac..7d4783b0f3c 100644
--- a/intern/cycles/kernel/closure/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
@@ -24,7 +24,6 @@
#include "../closure/bsdf_refraction.h"
#include "../closure/bsdf_transparent.h"
#include "../closure/bsdf_ashikhmin_shirley.h"
-#include "../closure/bsdf_westin.h"
#include "../closure/bsdf_toon.h"
#include "../closure/bsdf_hair.h"
#ifdef __SUBSURFACE__
@@ -109,14 +108,6 @@ ccl_device int bsdf_sample(KernelGlobals *kg, const ShaderData *sd, const Shader
label = bsdf_glossy_toon_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- label = bsdf_westin_backscatter_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- label = bsdf_westin_sheen_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
- eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
- break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
label = bsdf_hair_reflection_sample(sc, sd->Ng, sd->I, sd->dI.dx, sd->dI.dy, randu, randv,
eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
@@ -199,12 +190,6 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const Shade
case CLOSURE_BSDF_GLOSSY_TOON_ID:
eval = bsdf_glossy_toon_eval_reflect(sc, sd->I, omega_in, pdf);
break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
- break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
eval = bsdf_hair_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
break;
@@ -267,12 +252,6 @@ ccl_device float3 bsdf_eval(KernelGlobals *kg, const ShaderData *sd, const Shade
case CLOSURE_BSDF_GLOSSY_TOON_ID:
eval = bsdf_glossy_toon_eval_transmit(sc, sd->I, omega_in, pdf);
break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
- break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
eval = bsdf_hair_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
break;
@@ -353,12 +332,6 @@ ccl_device void bsdf_blur(KernelGlobals *kg, ShaderClosure *sc, float roughness)
case CLOSURE_BSDF_GLOSSY_TOON_ID:
bsdf_glossy_toon_blur(sc, roughness);
break;
- case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- bsdf_westin_backscatter_blur(sc, roughness);
- break;
- case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- bsdf_westin_sheen_blur(sc, roughness);
- break;
case CLOSURE_BSDF_HAIR_REFLECTION_ID:
case CLOSURE_BSDF_HAIR_TRANSMISSION_ID:
bsdf_hair_reflection_blur(sc, roughness);
diff --git a/intern/cycles/kernel/closure/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index a0c59e6cbc0..2079d26e5ad 100644
--- a/intern/cycles/kernel/closure/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -35,139 +35,38 @@
CCL_NAMESPACE_BEGIN
-/* Approximate erf and erfinv implementations
+/* Approximate erf and erfinv implementations.
+ * Implementation comes straight from Wikipedia:
*
- * Adapted from code (C) Copyright John Maddock 2006.
- * Use, modification and distribution are subject to the
- * Boost Software License, Version 1.0. (See accompanying file
- * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
-
-ccl_device float approx_erff_impl(float z)
-{
- float result;
-
- if(z < 0.5f) {
- if(z < 1e-10f) {
- if(z == 0) {
- result = 0;
- }
- else {
- float c = 0.0033791670f;
- result = z * 1.125f + z * c;
- }
- }
- else {
- float Y = 1.044948577f;
-
- float zz = z * z;
- float num = (((-0.007727583f * zz) + -0.050999073f)*zz + -0.338165134f)*zz + 0.083430589f;
- float denom = (((0.000370900f * zz) + 0.008585719f)*zz + 0.087522260f)*zz + 0.455004033f;
- result = z * (Y + num / denom);
- }
- }
- else if(z < 2.5f) {
- if(z < 1.5f) {
- float Y = 0.4059357643f;
- float fz = z - 0.5f;
-
- float num = (((0.088890036f * fz) + 0.191003695f)*fz + 0.178114665f)*fz + -0.098090592f;
- float denom = (((0.123850974f * fz) + 0.578052804f)*fz + 1.426280048f)*fz + 1.847590709f;
-
- result = Y + num / denom;
- result *= expf(-z * z) / z;
- }
- else {
- float Y = 0.506728172f;
- float fz = z - 1.5f;
- float num = (((0.017567943f * fz) + 0.043948189f)*fz + 0.038654037f)*fz + -0.024350047f;
- float denom = (((0.325732924f * fz) + 0.982403709f)*fz + 1.539914949f)*fz + 1;
-
- result = Y + num / denom;
- result *= expf(-z * z) / z;
- }
-
- result = 1 - result;
- }
- else {
- result = 1;
- }
-
- return result;
-}
+ * http://en.wikipedia.org/wiki/Error_function
+ *
+ * Some constants are baked into the code.
+ */
-ccl_device float approx_erff(float z)
+ccl_device_inline float approx_erff(float x)
{
float s = 1.0f;
-
- if(z < 0.0f) {
+ if(x < 0.0f) {
s = -1.0f;
- z = -z;
- }
-
- return s * approx_erff_impl(z);
-}
-
-ccl_device float approx_erfinvf_impl(float p, float q)
-{
- float result = 0;
-
- if(p <= 0.5f) {
- float Y = 0.089131474f;
- float g = p * (p + 10);
- float num = (((-0.012692614f * p) + 0.033480662f)*p + -0.008368748f)*p + -0.000508781f;
- float denom = (((1.562215583f * p) + -1.565745582f)*p + -0.970005043f)*p + 1.0f;
- float r = num / denom;
- result = g * Y + g * r;
+ x = -x;
}
- else if(q >= 0.25f) {
- float Y = 2.249481201f;
- float g = sqrtf(-2 * logf(q));
- float xs = q - 0.25f;
- float num = (((17.644729840f * xs) + 8.370503283f)*xs + 0.105264680f)*xs + -0.202433508f;
- float denom = (((-28.660818049f * xs) + 3.971343795f)*xs + 6.242641248f)*xs + 1.0f;
- float r = num / denom;
- result = g / (Y + r);
+ /* Such a clamp doesn't give much distortion to the output value
+ * and gives quite a few of the speedup.
+ */
+ if(x > 3.0f) {
+ return s;
}
- else {
- float x = sqrtf(-logf(q));
-
- if(x < 3) {
- float Y = 0.807220458f;
- float xs = x - 1.125f;
- float num = (((0.387079738f * xs) + 0.117030156f)*xs + -0.163794047f)*xs + -0.131102781f;
- float denom = (((4.778465929f * xs) + 5.381683457f)*xs + 3.466254072f)*xs + 1.0f;
- float R = num / denom;
- result = Y * x + R * x;
- }
- else {
- float Y = 0.939955711f;
- float xs = x - 3;
- float num = (((0.009508047f * xs) + 0.018557330f)*xs + -0.002224265f)*xs + -0.035035378f;
- float denom = (((0.220091105f * xs) + 0.762059164f)*xs + 1.365334981f)*xs + 1.0f;
- float R = num / denom;
- result = Y * x + R * x;
- }
- }
-
- return result;
+ float t = 1.0f / (1.0f + 0.47047f*x);
+ return s * (1.0f -
+ t*(0.3480242f + t*(-0.0958798f + t*0.7478556f)) * expf(-x*x));
}
-ccl_device float approx_erfinvf(float z)
+ccl_device_inline float approx_erfinvf(float x)
{
- float p, q, s;
-
- if(z < 0) {
- p = -z;
- q = 1 - p;
- s = -1;
- }
- else {
- p = z;
- q = 1 - z;
- s = 1;
- }
-
- return s * approx_erfinvf_impl(p, q);
+ float ln1_x2 = logf(1.0f - x*x);
+ float term = 4.546884979448f + ln1_x2 * 0.5f;
+ return copysignf(1.0f, x) *
+ sqrtf(sqrtf(term*term - ln1_x2 * 7.142230224076f) - term);
}
/* Beckmann and GGX microfacet importance sampling from:
diff --git a/intern/cycles/kernel/closure/bsdf_westin.h b/intern/cycles/kernel/closure/bsdf_westin.h
deleted file mode 100644
index 9dc1c00bb3d..00000000000
--- a/intern/cycles/kernel/closure/bsdf_westin.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * 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 Sony Pictures Imageworks 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.
- */
-
-#ifndef __BSDF_WESTIN_H__
-#define __BSDF_WESTIN_H__
-
-CCL_NAMESPACE_BEGIN
-
-/* WESTIN BACKSCATTER */
-
-ccl_device int bsdf_westin_backscatter_setup(ShaderClosure *sc)
-{
- float roughness = sc->data0;
- roughness = clamp(roughness, 1e-5f, 1.0f);
- float m_invroughness = 1.0f/roughness;
-
- sc->type = CLOSURE_BSDF_WESTIN_BACKSCATTER_ID;
- sc->data0 = m_invroughness;
-
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
-}
-
-ccl_device void bsdf_westin_backscatter_blur(ShaderClosure *sc, float roughness)
-{
- float m_invroughness = sc->data0;
- m_invroughness = min(1.0f/roughness, m_invroughness);
- sc->data0 = m_invroughness;
-}
-
-ccl_device float3 bsdf_westin_backscatter_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
-{
- float m_invroughness = sc->data0;
- float3 N = sc->N;
-
- // pdf is implicitly 0 (no indirect sampling)
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
- if(cosNO > 0 && cosNI > 0) {
- float cosine = dot(I, omega_in);
- *pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0;
- *pdf *= 0.5f * M_1_PI_F;
- return make_float3 (*pdf, *pdf, *pdf);
- }
- return make_float3 (0, 0, 0);
-}
-
-ccl_device float3 bsdf_westin_backscatter_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
-{
- return make_float3(0.0f, 0.0f, 0.0f);
-}
-
-ccl_device int bsdf_westin_backscatter_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
-{
- float m_invroughness = sc->data0;
- float3 N = sc->N;
-
- float cosNO = dot(N, I);
- if(cosNO > 0) {
-#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = dIdx;
- *domega_in_dy = dIdy;
-#endif
- float3 T, B;
- make_orthonormals (I, &T, &B);
- float phi = M_2PI_F * randu;
- float cosTheta = powf(randv, 1 / (m_invroughness + 1));
- float sinTheta2 = 1 - cosTheta * cosTheta;
- float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
- *omega_in = (cosf(phi) * sinTheta) * T +
- (sinf(phi) * sinTheta) * B +
- (cosTheta) * I;
- if(dot(Ng, *omega_in) > 0) {
- // common terms for pdf and eval
- float cosNI = dot(N, *omega_in);
- // make sure the direction we chose is still in the right hemisphere
- if(cosNI > 0)
- {
- *pdf = 0.5f * M_1_PI_F * powf(cosTheta, m_invroughness);
- *pdf = (m_invroughness + 1) * (*pdf);
- *eval = make_float3(*pdf, *pdf, *pdf);
- }
- }
- }
- return LABEL_REFLECT|LABEL_GLOSSY;
-}
-
-/* WESTIN SHEEN */
-
-ccl_device int bsdf_westin_sheen_setup(ShaderClosure *sc)
-{
- /* float edginess = sc->data0; */
- sc->type = CLOSURE_BSDF_WESTIN_SHEEN_ID;
- return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
-}
-
-ccl_device void bsdf_westin_sheen_blur(ShaderClosure *sc, float roughness)
-{
-}
-
-ccl_device float3 bsdf_westin_sheen_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
-{
- float m_edginess = sc->data0;
- float3 N = sc->N;
-
- // pdf is implicitly 0 (no indirect sampling)
- float cosNO = dot(N, I);
- float cosNI = dot(N, omega_in);
- if(cosNO > 0 && cosNI > 0) {
- float sinNO2 = 1 - cosNO * cosNO;
- *pdf = cosNI * M_1_PI_F;
- float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * (*pdf) : 0;
- return make_float3 (westin, westin, westin);
- }
- return make_float3 (0, 0, 0);
-}
-
-ccl_device float3 bsdf_westin_sheen_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
-{
- return make_float3(0.0f, 0.0f, 0.0f);
-}
-
-ccl_device int bsdf_westin_sheen_sample(const ShaderClosure *sc, float3 Ng, float3 I, float3 dIdx, float3 dIdy, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
-{
- float m_edginess = sc->data0;
- float3 N = sc->N;
-
- // we are viewing the surface from the right side - send a ray out with cosine
- // distribution over the hemisphere
- sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
- if(dot(Ng, *omega_in) > 0) {
- // TODO: account for sheen when sampling
- float cosNO = dot(N, I);
- float sinNO2 = 1 - cosNO * cosNO;
- float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * (*pdf) : 0;
- *eval = make_float3(westin, westin, westin);
-#ifdef __RAY_DIFFERENTIALS__
- // TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
- *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
-#endif
- }
- else {
- pdf = 0;
- }
- return LABEL_REFLECT|LABEL_DIFFUSE;
-}
-
-CCL_NAMESPACE_END
-
-#endif /* __BSDF_WESTIN_H__ */
-
diff --git a/intern/cycles/kernel/geom/geom_bvh.h b/intern/cycles/kernel/geom/geom_bvh.h
index dd7c25d581d..c5336e086b7 100644
--- a/intern/cycles/kernel/geom/geom_bvh.h
+++ b/intern/cycles/kernel/geom/geom_bvh.h
@@ -28,6 +28,13 @@
CCL_NAMESPACE_BEGIN
+/* Don't inline intersect functions on GPU, this is faster */
+#ifdef __KERNEL_GPU__
+#define ccl_device_intersect ccl_device_noinline
+#else
+#define ccl_device_intersect ccl_device_inline
+#endif
+
/* BVH intersection function variations */
#define BVH_INSTANCING 1
@@ -35,6 +42,8 @@ CCL_NAMESPACE_BEGIN
#define BVH_HAIR 4
#define BVH_HAIR_MINIMUM_WIDTH 8
+/* Regular BVH traversal */
+
#define BVH_FUNCTION_NAME bvh_intersect
#define BVH_FUNCTION_FEATURES 0
#include "geom_bvh_traversal.h"
@@ -63,6 +72,8 @@ CCL_NAMESPACE_BEGIN
#include "geom_bvh_traversal.h"
#endif
+/* Subsurface scattering BVH traversal */
+
#if defined(__SUBSURFACE__)
#define BVH_FUNCTION_NAME bvh_intersect_subsurface
#define BVH_FUNCTION_FEATURES 0
@@ -93,47 +104,72 @@ CCL_NAMESPACE_BEGIN
#include "geom_bvh_subsurface.h"
#endif
+/* Record all BVH intersection for shadows */
+
#if defined(__SHADOW_RECORD_ALL__)
#define BVH_FUNCTION_NAME bvh_intersect_shadow_all
#define BVH_FUNCTION_FEATURES 0
#include "geom_bvh_shadow.h"
#endif
-#if defined(__SUBSURFACE__) && defined(__INSTANCING__)
+#if defined(__SHADOW_RECORD_ALL__) && defined(__INSTANCING__)
#define BVH_FUNCTION_NAME bvh_intersect_shadow_all_instancing
#define BVH_FUNCTION_FEATURES BVH_INSTANCING
#include "geom_bvh_shadow.h"
#endif
-#if defined(__SUBSURFACE__) && defined(__HAIR__)
+#if defined(__SHADOW_RECORD_ALL__) && defined(__HAIR__)
#define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR
#include "geom_bvh_shadow.h"
#endif
-#if defined(__SUBSURFACE__) && defined(__OBJECT_MOTION__)
+#if defined(__SHADOW_RECORD_ALL__) && defined(__OBJECT_MOTION__)
#define BVH_FUNCTION_NAME bvh_intersect_shadow_all_motion
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
#include "geom_bvh_shadow.h"
#endif
-#if defined(__SUBSURFACE__) && defined(__HAIR__) && defined(__OBJECT_MOTION__)
+#if defined(__SHADOW_RECORD_ALL__) && defined(__HAIR__) && defined(__OBJECT_MOTION__)
#define BVH_FUNCTION_NAME bvh_intersect_shadow_all_hair_motion
#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_MOTION
#include "geom_bvh_shadow.h"
#endif
-/* to work around titan bug when using arrays instead of textures */
-#if !defined(__KERNEL_CUDA__) || defined(__KERNEL_CUDA_TEX_STORAGE__)
-ccl_device_inline
-#else
-ccl_device_noinline
+/* Camera inside Volume BVH intersection */
+
+#if defined(__VOLUME__)
+#define BVH_FUNCTION_NAME bvh_intersect_volume
+#define BVH_FUNCTION_FEATURES 0
+#include "geom_bvh_volume.h"
#endif
-#ifdef __HAIR__
-bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect, uint *lcg_state, float difl, float extmax)
-#else
-bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
+
+#if defined(__VOLUME__) && defined(__INSTANCING__)
+#define BVH_FUNCTION_NAME bvh_intersect_volume_instancing
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING
+#include "geom_bvh_volume.h"
+#endif
+
+#if defined(__VOLUME__) && defined(__HAIR__)
+#define BVH_FUNCTION_NAME bvh_intersect_volume_hair
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH
+#include "geom_bvh_volume.h"
+#endif
+
+#if defined(__VOLUME__) && defined(__OBJECT_MOTION__)
+#define BVH_FUNCTION_NAME bvh_intersect_volume_motion
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_MOTION
+#include "geom_bvh_volume.h"
+#endif
+
+#if defined(__VOLUME__) && defined(__HAIR__) && defined(__OBJECT_MOTION__)
+#define BVH_FUNCTION_NAME bvh_intersect_volume_hair_motion
+#define BVH_FUNCTION_FEATURES BVH_INSTANCING|BVH_HAIR|BVH_HAIR_MINIMUM_WIDTH|BVH_MOTION
+#include "geom_bvh_volume.h"
#endif
+
+ccl_device_intersect bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect,
+ uint *lcg_state, float difl, float extmax)
{
#ifdef __OBJECT_MOTION__
if(kernel_data.bvh.have_motion) {
@@ -170,14 +206,8 @@ bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, I
#endif /* __KERNEL_CPU__ */
}
-/* to work around titan bug when using arrays instead of textures */
#ifdef __SUBSURFACE__
-#if !defined(__KERNEL_CUDA__) || defined(__KERNEL_CUDA_TEX_STORAGE__)
-ccl_device_inline
-#else
-ccl_device_noinline
-#endif
-uint scene_intersect_subsurface(KernelGlobals *kg, const Ray *ray, Intersection *isect, int subsurface_object, uint *lcg_state, int max_hits)
+ccl_device_intersect uint scene_intersect_subsurface(KernelGlobals *kg, const Ray *ray, Intersection *isect, int subsurface_object, uint *lcg_state, int max_hits)
{
#ifdef __OBJECT_MOTION__
if(kernel_data.bvh.have_motion) {
@@ -215,14 +245,8 @@ uint scene_intersect_subsurface(KernelGlobals *kg, const Ray *ray, Intersection
}
#endif
-/* to work around titan bug when using arrays instead of textures */
#ifdef __SHADOW_RECORD_ALL__
-#if !defined(__KERNEL_CUDA__) || defined(__KERNEL_CUDA_TEX_STORAGE__)
-ccl_device_inline
-#else
-ccl_device_noinline
-#endif
-uint scene_intersect_shadow_all(KernelGlobals *kg, const Ray *ray, Intersection *isect, uint max_hits, uint *num_hits)
+ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg, const Ray *ray, Intersection *isect, uint max_hits, uint *num_hits)
{
#ifdef __OBJECT_MOTION__
if(kernel_data.bvh.have_motion) {
@@ -240,20 +264,50 @@ uint scene_intersect_shadow_all(KernelGlobals *kg, const Ray *ray, Intersection
return bvh_intersect_shadow_all_hair(kg, ray, isect, max_hits, num_hits);
#endif /* __HAIR__ */
-#ifdef __KERNEL_CPU__
-
#ifdef __INSTANCING__
if(kernel_data.bvh.have_instancing)
return bvh_intersect_shadow_all_instancing(kg, ray, isect, max_hits, num_hits);
#endif /* __INSTANCING__ */
return bvh_intersect_shadow_all(kg, ray, isect, max_hits, num_hits);
+}
+#endif
+
+#ifdef __VOLUME__
+ccl_device_intersect bool scene_intersect_volume(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect)
+{
+#ifdef __OBJECT_MOTION__
+ if(kernel_data.bvh.have_motion) {
+#ifdef __HAIR__
+ if(kernel_data.bvh.have_curves)
+ return bvh_intersect_volume_hair_motion(kg, ray, isect);
+#endif /* __HAIR__ */
+
+ return bvh_intersect_volume_motion(kg, ray, isect);
+ }
+#endif /* __OBJECT_MOTION__ */
+
+#ifdef __HAIR__
+ if(kernel_data.bvh.have_curves)
+ return bvh_intersect_volume_hair(kg, ray, isect);
+#endif /* __HAIR__ */
+
+#ifdef __KERNEL_CPU__
+
+#ifdef __INSTANCING__
+ if(kernel_data.bvh.have_instancing)
+ return bvh_intersect_volume_instancing(kg, ray, isect);
+#endif /* __INSTANCING__ */
+
+ return bvh_intersect_volume(kg, ray, isect);
#else /* __KERNEL_CPU__ */
#ifdef __INSTANCING__
- return bvh_intersect_shadow_all_instancing(kg, ray, isect, max_hits, num_hits);
+ return bvh_intersect_volume_instancing(kg, ray, isect);
#else
- return bvh_intersect_shadow_all(kg, ray, isect, max_hits, num_hits);
+ return bvh_intersect_volume(kg, ray, isect);
#endif /* __INSTANCING__ */
#endif /* __KERNEL_CPU__ */
diff --git a/intern/cycles/kernel/geom/geom_bvh_shadow.h b/intern/cycles/kernel/geom/geom_bvh_shadow.h
index 1f6e4942fab..aee4097d77e 100644
--- a/intern/cycles/kernel/geom/geom_bvh_shadow.h
+++ b/intern/cycles/kernel/geom/geom_bvh_shadow.h
@@ -252,7 +252,7 @@ ccl_device bool BVH_FUNCTION_NAME
if(kernel_tex_fetch(__prim_type, isect_array->prim) & PRIMITIVE_ALL_TRIANGLE)
#endif
{
- shader = __float_as_int(kernel_tex_fetch(__tri_shader, prim));
+ shader = kernel_tex_fetch(__tri_shader, prim);
}
#ifdef __HAIR__
else {
diff --git a/intern/cycles/kernel/geom/geom_bvh_traversal.h b/intern/cycles/kernel/geom/geom_bvh_traversal.h
index e39228c33de..eed54a4d00d 100644
--- a/intern/cycles/kernel/geom/geom_bvh_traversal.h
+++ b/intern/cycles/kernel/geom/geom_bvh_traversal.h
@@ -68,6 +68,10 @@ ccl_device bool BVH_FUNCTION_NAME
isect->u = 0.0f;
isect->v = 0.0f;
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps = 0;
+#endif
+
#if defined(__KERNEL_SSE2__)
const shuffle_swap_t shuf_identity = shuffle_swap_identity();
const shuffle_swap_t shuf_swap = shuffle_swap_swap();
@@ -226,6 +230,10 @@ ccl_device bool BVH_FUNCTION_NAME
--stackPtr;
}
}
+
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps++;
+#endif
}
/* if node is leaf, fetch triangle list */
@@ -274,6 +282,10 @@ ccl_device bool BVH_FUNCTION_NAME
}
}
+#if defined(__KERNEL_DEBUG__)
+ isect->num_traversal_steps++;
+#endif
+
/* shadow ray early termination */
#if defined(__KERNEL_SSE2__)
if(hit) {
diff --git a/intern/cycles/kernel/geom/geom_bvh_volume.h b/intern/cycles/kernel/geom/geom_bvh_volume.h
new file mode 100644
index 00000000000..aac0a18647a
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_bvh_volume.h
@@ -0,0 +1,322 @@
+/*
+ * Adapted from code Copyright 2009-2010 NVIDIA Corporation,
+ * and code copyright 2009-2012 Intel Corporation
+ *
+ * Modifications Copyright 2011-2014, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This is a template BVH traversal function for volumes, where
+ * various features can be enabled/disabled. This way we can compile optimized
+ * versions for each case without new features slowing things down.
+ *
+ * BVH_INSTANCING: object instancing
+ * BVH_HAIR: hair curve rendering
+ * BVH_MOTION: motion blur rendering
+ *
+ */
+
+#define FEATURE(f) (((BVH_FUNCTION_FEATURES) & (f)) != 0)
+
+ccl_device bool BVH_FUNCTION_NAME(KernelGlobals *kg,
+ const Ray *ray,
+ Intersection *isect)
+{
+ /* todo:
+ * - test if pushing distance on the stack helps (for non shadow rays)
+ * - separate version for shadow rays
+ * - likely and unlikely for if() statements
+ * - test restrict attribute for pointers
+ */
+
+ /* traversal stack in CUDA thread-local memory */
+ int traversalStack[BVH_STACK_SIZE];
+ traversalStack[0] = ENTRYPOINT_SENTINEL;
+
+ /* traversal variables in registers */
+ int stackPtr = 0;
+ int nodeAddr = kernel_data.bvh.root;
+
+ /* ray parameters in registers */
+ float3 P = ray->P;
+ float3 dir = bvh_clamp_direction(ray->D);
+ float3 idir = bvh_inverse_direction(dir);
+ int object = OBJECT_NONE;
+
+ const uint visibility = PATH_RAY_ALL_VISIBILITY;
+
+#if FEATURE(BVH_MOTION)
+ Transform ob_tfm;
+#endif
+
+ isect->t = ray->t;
+ isect->object = OBJECT_NONE;
+ isect->prim = PRIM_NONE;
+ isect->u = 0.0f;
+ isect->v = 0.0f;
+
+#if defined(__KERNEL_SSE2__)
+ const shuffle_swap_t shuf_identity = shuffle_swap_identity();
+ const shuffle_swap_t shuf_swap = shuffle_swap_swap();
+
+ const ssef pn = cast(ssei(0, 0, 0x80000000, 0x80000000));
+ ssef Psplat[3], idirsplat[3];
+ shuffle_swap_t shufflexyz[3];
+
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
+
+ ssef tsplat(0.0f, 0.0f, -isect->t, -isect->t);
+
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+#endif
+
+ /* traversal loop */
+ do {
+ do {
+ /* traverse internal nodes */
+ while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL) {
+ bool traverseChild0, traverseChild1;
+ int nodeAddrChild1;
+
+#if !defined(__KERNEL_SSE2__)
+ /* Intersect two child bounding boxes, non-SSE version */
+ float t = isect->t;
+
+ /* fetch node data */
+ float4 node0 = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+0);
+ float4 node1 = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+1);
+ float4 node2 = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+2);
+ float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*BVH_NODE_SIZE+3);
+
+ /* intersect ray against child nodes */
+ NO_EXTENDED_PRECISION float c0lox = (node0.x - P.x) * idir.x;
+ NO_EXTENDED_PRECISION float c0hix = (node0.z - P.x) * idir.x;
+ NO_EXTENDED_PRECISION float c0loy = (node1.x - P.y) * idir.y;
+ NO_EXTENDED_PRECISION float c0hiy = (node1.z - P.y) * idir.y;
+ NO_EXTENDED_PRECISION float c0loz = (node2.x - P.z) * idir.z;
+ NO_EXTENDED_PRECISION float c0hiz = (node2.z - P.z) * idir.z;
+ NO_EXTENDED_PRECISION float c0min = max4(min(c0lox, c0hix), min(c0loy, c0hiy), min(c0loz, c0hiz), 0.0f);
+ NO_EXTENDED_PRECISION float c0max = min4(max(c0lox, c0hix), max(c0loy, c0hiy), max(c0loz, c0hiz), t);
+
+ NO_EXTENDED_PRECISION float c1lox = (node0.y - P.x) * idir.x;
+ NO_EXTENDED_PRECISION float c1hix = (node0.w - P.x) * idir.x;
+ NO_EXTENDED_PRECISION float c1loy = (node1.y - P.y) * idir.y;
+ NO_EXTENDED_PRECISION float c1hiy = (node1.w - P.y) * idir.y;
+ NO_EXTENDED_PRECISION float c1loz = (node2.y - P.z) * idir.z;
+ NO_EXTENDED_PRECISION float c1hiz = (node2.w - P.z) * idir.z;
+ NO_EXTENDED_PRECISION float c1min = max4(min(c1lox, c1hix), min(c1loy, c1hiy), min(c1loz, c1hiz), 0.0f);
+ NO_EXTENDED_PRECISION float c1max = min4(max(c1lox, c1hix), max(c1loy, c1hiy), max(c1loz, c1hiz), t);
+
+ /* decide which nodes to traverse next */
+#ifdef __VISIBILITY_FLAG__
+ /* this visibility test gives a 5% performance hit, how to solve? */
+ traverseChild0 = (c0max >= c0min) && (__float_as_uint(cnodes.z) & visibility);
+ traverseChild1 = (c1max >= c1min) && (__float_as_uint(cnodes.w) & visibility);
+#else
+ traverseChild0 = (c0max >= c0min);
+ traverseChild1 = (c1max >= c1min);
+#endif
+
+#else // __KERNEL_SSE2__
+ /* Intersect two child bounding boxes, SSE3 version adapted from Embree */
+
+ /* fetch node data */
+ const ssef *bvh_nodes = (ssef*)kg->__bvh_nodes.data + nodeAddr*BVH_NODE_SIZE;
+ const float4 cnodes = ((float4*)bvh_nodes)[3];
+
+ /* intersect ray against child nodes */
+ const ssef tminmaxx = (shuffle_swap(bvh_nodes[0], shufflexyz[0]) - Psplat[0]) * idirsplat[0];
+ const ssef tminmaxy = (shuffle_swap(bvh_nodes[1], shufflexyz[1]) - Psplat[1]) * idirsplat[1];
+ const ssef tminmaxz = (shuffle_swap(bvh_nodes[2], shufflexyz[2]) - Psplat[2]) * idirsplat[2];
+
+ /* calculate { c0min, c1min, -c0max, -c1max} */
+ ssef minmax = max(max(tminmaxx, tminmaxy), max(tminmaxz, tsplat));
+ const ssef tminmax = minmax ^ pn;
+
+ const sseb lrhit = tminmax <= shuffle<2, 3, 0, 1>(tminmax);
+
+ /* decide which nodes to traverse next */
+#ifdef __VISIBILITY_FLAG__
+ /* this visibility test gives a 5% performance hit, how to solve? */
+ traverseChild0 = (movemask(lrhit) & 1) && (__float_as_uint(cnodes.z) & visibility);
+ traverseChild1 = (movemask(lrhit) & 2) && (__float_as_uint(cnodes.w) & visibility);
+#else
+ traverseChild0 = (movemask(lrhit) & 1);
+ traverseChild1 = (movemask(lrhit) & 2);
+#endif
+#endif // __KERNEL_SSE2__
+
+ nodeAddr = __float_as_int(cnodes.x);
+ nodeAddrChild1 = __float_as_int(cnodes.y);
+
+ if(traverseChild0 && traverseChild1) {
+ /* both children were intersected, push the farther one */
+#if !defined(__KERNEL_SSE2__)
+ bool closestChild1 = (c1min < c0min);
+#else
+ bool closestChild1 = tminmax[1] < tminmax[0];
+#endif
+
+ if(closestChild1) {
+ int tmp = nodeAddr;
+ nodeAddr = nodeAddrChild1;
+ nodeAddrChild1 = tmp;
+ }
+
+ ++stackPtr;
+ traversalStack[stackPtr] = nodeAddrChild1;
+ }
+ else {
+ /* one child was intersected */
+ if(traverseChild1) {
+ nodeAddr = nodeAddrChild1;
+ }
+ else if(!traverseChild0) {
+ /* neither child was intersected */
+ nodeAddr = traversalStack[stackPtr];
+ --stackPtr;
+ }
+ }
+ }
+
+ /* if node is leaf, fetch triangle list */
+ if(nodeAddr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+(BVH_NODE_SIZE-1));
+ int primAddr = __float_as_int(leaf.x);
+
+#if FEATURE(BVH_INSTANCING)
+ if(primAddr >= 0) {
+#endif
+ int primAddr2 = __float_as_int(leaf.y);
+
+ /* pop */
+ nodeAddr = traversalStack[stackPtr];
+ --stackPtr;
+
+ /* primitive intersection */
+ for(; primAddr < primAddr2; primAddr++) {
+ /* only primitives from volume object */
+ uint tri_object = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, primAddr): object;
+ int object_flag = kernel_tex_fetch(__object_flag, tri_object);
+
+ if((object_flag & SD_OBJECT_HAS_VOLUME) == 0) {
+ continue;
+ }
+
+ /* intersect ray against primitive */
+ uint type = kernel_tex_fetch(__prim_type, primAddr);
+
+ switch(type & PRIMITIVE_ALL) {
+ case PRIMITIVE_TRIANGLE: {
+ triangle_intersect(kg, isect, P, dir, visibility, object, primAddr);
+ break;
+ }
+#if FEATURE(BVH_MOTION)
+ case PRIMITIVE_MOTION_TRIANGLE: {
+ motion_triangle_intersect(kg, isect, P, dir, ray->time, visibility, object, primAddr);
+ break;
+ }
+#endif
+#if FEATURE(BVH_HAIR)
+ case PRIMITIVE_CURVE:
+ case PRIMITIVE_MOTION_CURVE: {
+ if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE)
+ bvh_cardinal_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, NULL, 0, 0);
+ else
+ bvh_curve_intersect(kg, isect, P, dir, visibility, object, primAddr, ray->time, type, NULL, 0, 0);
+ break;
+ }
+#endif
+ default: {
+ break;
+ }
+ }
+ }
+ }
+#if FEATURE(BVH_INSTANCING)
+ else {
+ /* instance push */
+ object = kernel_tex_fetch(__prim_object, -primAddr-1);
+ int object_flag = kernel_tex_fetch(__object_flag, object);
+
+ if(object_flag & SD_OBJECT_HAS_VOLUME) {
+
+#if FEATURE(BVH_MOTION)
+ bvh_instance_motion_push(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+#else
+ bvh_instance_push(kg, object, ray, &P, &dir, &idir, &isect->t);
+#endif
+
+#if defined(__KERNEL_SSE2__)
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
+
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+#endif
+
+ ++stackPtr;
+ traversalStack[stackPtr] = ENTRYPOINT_SENTINEL;
+
+ nodeAddr = kernel_tex_fetch(__object_node, object);
+ }
+ else {
+ /* pop */
+ nodeAddr = traversalStack[stackPtr];
+ --stackPtr;
+ }
+ }
+ }
+#endif
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+#if FEATURE(BVH_INSTANCING)
+ if(stackPtr >= 0) {
+ kernel_assert(object != OBJECT_NONE);
+
+ /* instance pop */
+#if FEATURE(BVH_MOTION)
+ bvh_instance_motion_pop(kg, object, ray, &P, &dir, &idir, &isect->t, &ob_tfm);
+#else
+ bvh_instance_pop(kg, object, ray, &P, &dir, &idir, &isect->t);
+#endif
+
+#if defined(__KERNEL_SSE2__)
+ Psplat[0] = ssef(P.x);
+ Psplat[1] = ssef(P.y);
+ Psplat[2] = ssef(P.z);
+
+ tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
+
+ gen_idirsplat_swap(pn, shuf_identity, shuf_swap, idir, idirsplat, shufflexyz);
+#endif
+
+ object = OBJECT_NONE;
+ nodeAddr = traversalStack[stackPtr];
+ --stackPtr;
+ }
+#endif
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+ return (isect->prim != PRIM_NONE);
+}
+
+#undef FEATURE
+#undef BVH_FUNCTION_NAME
+#undef BVH_FUNCTION_FEATURES
+
diff --git a/intern/cycles/kernel/geom/geom_motion_triangle.h b/intern/cycles/kernel/geom/geom_motion_triangle.h
index 7409aa0d014..b275b89a8a4 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle.h
@@ -233,7 +233,7 @@ ccl_device_inline float3 motion_triangle_refine_subsurface(KernelGlobals *kg, Sh
ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray, bool subsurface)
{
/* get shader */
- sd->shader = __float_as_int(kernel_tex_fetch(__tri_shader, sd->prim));
+ sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
/* get motion info */
int numsteps, numverts;
diff --git a/intern/cycles/kernel/geom/geom_triangle.h b/intern/cycles/kernel/geom/geom_triangle.h
index 41e9d183a96..3d3a5e72485 100644
--- a/intern/cycles/kernel/geom/geom_triangle.h
+++ b/intern/cycles/kernel/geom/geom_triangle.h
@@ -157,7 +157,7 @@ ccl_device_inline void triangle_point_normal(KernelGlobals *kg, int object, int
*Ng = normalize(cross(v1 - v0, v2 - v0));
/* shader`*/
- *shader = __float_as_int(kernel_tex_fetch(__tri_shader, prim));
+ *shader = kernel_tex_fetch(__tri_shader, prim);
}
/* Triangle vertex locations */
diff --git a/intern/cycles/kernel/kernel.cu b/intern/cycles/kernel/kernel.cu
index d5b5293664c..9ed4592f604 100644
--- a/intern/cycles/kernel/kernel.cu
+++ b/intern/cycles/kernel/kernel.cu
@@ -52,8 +52,8 @@
#define CUDA_KERNEL_MAX_REGISTERS 63
#define CUDA_KERNEL_BRANCHED_MAX_REGISTERS 63
-/* 5.0 */
-#elif __CUDA_ARCH__ == 500
+/* 5.0 and 5.2 */
+#elif __CUDA_ARCH__ == 500 || __CUDA_ARCH__ == 520
#define CUDA_MULTIPRESSOR_MAX_REGISTERS 65536
#define CUDA_MULTIPROCESSOR_MAX_BLOCKS 32
#define CUDA_BLOCK_MAX_THREADS 1024
diff --git a/intern/cycles/kernel/kernel_bake.h b/intern/cycles/kernel/kernel_bake.h
index dfbb49db7e6..a1ec080e3d3 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -33,7 +33,7 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
path_radiance_init(&L_sample, kernel_data.film.use_light_pass);
/* init path state */
- path_state_init(kg, &state, &rng, sample);
+ path_state_init(kg, &state, &rng, sample, NULL);
/* evaluate surface shader */
float rbsdf = path_state_rng_1D(kg, &rng, &state, PRNG_BSDF);
@@ -96,7 +96,7 @@ ccl_device void compute_light_pass(KernelGlobals *kg, ShaderData *sd, PathRadian
/* sample subsurface scattering */
if((is_combined || is_sss_sample) && (sd->flag & SD_BSSRDF)) {
/* when mixing BSSRDF and BSDF closures we should skip BSDF lighting if scattering was successful */
- kernel_branched_path_subsurface_scatter(kg, sd, &L_sample, &state, &rng, throughput);
+ kernel_branched_path_subsurface_scatter(kg, sd, &L_sample, &state, &rng, &ray, throughput);
}
#endif
diff --git a/intern/cycles/kernel/kernel_compat_cpu.h b/intern/cycles/kernel/kernel_compat_cpu.h
index c2aab93c87b..25531843993 100644
--- a/intern/cycles/kernel/kernel_compat_cpu.h
+++ b/intern/cycles/kernel/kernel_compat_cpu.h
@@ -25,6 +25,13 @@
#include "util_half.h"
#include "util_types.h"
+/* On 64bit linux single precision exponent is really slow comparing to the
+ * double precision version, even with float<->double conversion involved.
+ */
+#if !defined(__KERNEL_GPU__) && defined(__linux__) && defined(__x86_64__)
+# define expf(x) ((float)exp((double)x))
+#endif
+
CCL_NAMESPACE_BEGIN
/* Assertions inside the kernel only work for the CPU device, so we wrap it in
diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h
index 9e58ebff599..78b3fd012dd 100644
--- a/intern/cycles/kernel/kernel_compat_opencl.h
+++ b/intern/cycles/kernel/kernel_compat_opencl.h
@@ -24,14 +24,6 @@
#define CCL_NAMESPACE_BEGIN
#define CCL_NAMESPACE_END
-#ifdef __KERNEL_OPENCL_AMD__
-#define __CL_NO_FLOAT3__
-#endif
-
-#ifdef __CL_NO_FLOAT3__
-#define float3 float4
-#endif
-
#ifdef __CL_NOINLINE__
#define ccl_noinline __attribute__((noinline))
#else
@@ -73,11 +65,7 @@
#endif
#define make_float2(x, y) ((float2)(x, y))
-#ifdef __CL_NO_FLOAT3__
-#define make_float3(x, y, z) ((float4)(x, y, z, 0.0f))
-#else
#define make_float3(x, y, z) ((float3)(x, y, z))
-#endif
#define make_float4(x, y, z, w) ((float4)(x, y, z, w))
#define make_int2(x, y) ((int2)(x, y))
#define make_int3(x, y, z) ((int3)(x, y, z))
diff --git a/intern/cycles/kernel/kernel_debug.h b/intern/cycles/kernel/kernel_debug.h
new file mode 100644
index 00000000000..bf1bc0e9db8
--- /dev/null
+++ b/intern/cycles/kernel/kernel_debug.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2011-2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+CCL_NAMESPACE_BEGIN
+
+ccl_device_inline void debug_data_init(DebugData *debug_data)
+{
+ debug_data->num_bvh_traversal_steps = 0;
+}
+
+ccl_device_inline void kernel_write_debug_passes(KernelGlobals *kg,
+ ccl_global float *buffer,
+ PathState *state,
+ DebugData *debug_data,
+ int sample)
+{
+ int flag = kernel_data.film.pass_flag;
+ if(flag & PASS_BVH_TRAVERSAL_STEPS) {
+ kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversal_steps,
+ sample,
+ debug_data->num_bvh_traversal_steps);
+ }
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index 515854b6e9c..c03229f0a3a 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -45,6 +45,10 @@
#include "kernel_path_surface.h"
#include "kernel_path_volume.h"
+#ifdef __KERNEL_DEBUG__
+#include "kernel_debug.h"
+#endif
+
CCL_NAMESPACE_BEGIN
ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray,
@@ -55,11 +59,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, Ray ray,
/* intersect scene */
Intersection isect;
uint visibility = path_state_ray_visibility(kg, &state);
-#ifdef __HAIR__
bool hit = scene_intersect(kg, &ray, visibility, &isect, NULL, 0.0f, 0.0f);
-#else
- bool hit = scene_intersect(kg, &ray, visibility, &isect);
-#endif
#ifdef __LAMP_MIS__
if(kernel_data.integrator.use_lamp_mis && !(state.flag & PATH_RAY_CAMERA)) {
@@ -363,6 +363,30 @@ ccl_device void kernel_branched_path_ao(KernelGlobals *kg, ShaderData *sd, PathR
}
#ifdef __SUBSURFACE__
+
+#ifdef __VOLUME__
+ccl_device void kernel_path_subsurface_update_volume_stack(KernelGlobals *kg,
+ Ray *ray,
+ VolumeStack *stack)
+{
+ kernel_assert(kernel_data.integrator.use_volumes);
+
+ Ray volume_ray = *ray;
+ Intersection isect;
+
+ while(scene_intersect_volume(kg, &volume_ray, &isect))
+ {
+ ShaderData sd;
+ shader_setup_from_ray(kg, &sd, &isect, &volume_ray, 0, 0);
+ kernel_volume_stack_enter_exit(kg, &sd, stack);
+
+ /* Move ray forward. */
+ volume_ray.P = ray_offset(sd.P, -sd.Ng);
+ volume_ray.t -= sd.ray_length;
+ }
+}
+#endif
+
ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, Ray *ray, float3 *throughput)
{
float bssrdf_probability;
@@ -379,6 +403,11 @@ ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd
float bssrdf_u, bssrdf_v;
path_state_rng_2D(kg, rng, state, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
int num_hits = subsurface_scatter_multi_step(kg, sd, bssrdf_sd, state->flag, sc, &lcg_state, bssrdf_u, bssrdf_v, false);
+#ifdef __VOLUME__
+ Ray volume_ray = *ray;
+ bool need_update_volume_stack = kernel_data.integrator.use_volumes &&
+ sd->flag & SD_OBJECT_INTERSECTS_VOLUME;
+#endif
/* compute lighting with the BSDF closure */
for(int hit = 0; hit < num_hits; hit++) {
@@ -396,6 +425,22 @@ ccl_device bool kernel_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd
hit_state.ray_t = 0.0f;
#endif
+#ifdef __VOLUME__
+ if(need_update_volume_stack) {
+ /* Setup ray from previous surface point to the new one. */
+ volume_ray.D = normalize_len(hit_ray.P - volume_ray.P,
+ &volume_ray.t);
+
+ kernel_path_subsurface_update_volume_stack(
+ kg,
+ &volume_ray,
+ hit_state.volume_stack);
+
+ /* Move volume ray forward. */
+ volume_ray.P = hit_ray.P;
+ }
+#endif
+
kernel_path_indirect(kg, rng, hit_ray, tp, state->num_samples, hit_state, L);
/* for render passes, sum and reset indirect light pass variables
@@ -420,7 +465,12 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
path_radiance_init(&L, kernel_data.film.use_light_pass);
PathState state;
- path_state_init(kg, &state, rng, sample);
+ path_state_init(kg, &state, rng, sample, &ray);
+
+#ifdef __KERNEL_DEBUG__
+ DebugData debug_data;
+ debug_data_init(&debug_data);
+#endif
/* path iteration */
for(;;) {
@@ -445,7 +495,13 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
bool hit = scene_intersect(kg, &ray, visibility, &isect, &lcg_state, difl, extmax);
#else
- bool hit = scene_intersect(kg, &ray, visibility, &isect);
+ bool hit = scene_intersect(kg, &ray, visibility, &isect, NULL, 0.0f, 0.0f);
+#endif
+
+#ifdef __KERNEL_DEBUG__
+ if(state.flag & PATH_RAY_CAMERA) {
+ debug_data.num_bvh_traversal_steps += isect.num_traversal_steps;
+ }
#endif
#ifdef __LAMP_MIS__
@@ -668,6 +724,10 @@ ccl_device float4 kernel_path_integrate(KernelGlobals *kg, RNG *rng, int sample,
kernel_write_light_passes(kg, buffer, &L, sample);
+#ifdef __KERNEL_DEBUG__
+ kernel_write_debug_passes(kg, buffer, &state, &debug_data, sample);
+#endif
+
return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent);
}
@@ -722,7 +782,13 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba
}
#ifdef __SUBSURFACE__
-ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, ShaderData *sd, PathRadiance *L, PathState *state, RNG *rng, float3 throughput)
+ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
+ ShaderData *sd,
+ PathRadiance *L,
+ PathState *state,
+ RNG *rng,
+ Ray *ray,
+ float3 throughput)
{
for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
@@ -745,6 +811,11 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, Shade
float bssrdf_u, bssrdf_v;
path_branched_rng_2D(kg, &bssrdf_rng, state, j, num_samples, PRNG_BSDF_U, &bssrdf_u, &bssrdf_v);
int num_hits = subsurface_scatter_multi_step(kg, sd, bssrdf_sd, state->flag, sc, &lcg_state, bssrdf_u, bssrdf_v, true);
+#ifdef __VOLUME__
+ Ray volume_ray = *ray;
+ bool need_update_volume_stack = kernel_data.integrator.use_volumes &&
+ sd->flag & SD_OBJECT_INTERSECTS_VOLUME;
+#endif
/* compute lighting with the BSDF closure */
for(int hit = 0; hit < num_hits; hit++) {
@@ -752,6 +823,23 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg, Shade
path_state_branch(&hit_state, j, num_samples);
+#ifdef __VOLUME__
+ if(need_update_volume_stack) {
+ /* Setup ray from previous surface point to the new one. */
+ float3 P = ray_offset(bssrdf_sd[hit].P, -bssrdf_sd[hit].Ng);
+ volume_ray.D = normalize_len(P - volume_ray.P,
+ &volume_ray.t);
+
+ kernel_path_subsurface_update_volume_stack(
+ kg,
+ &volume_ray,
+ hit_state.volume_stack);
+
+ /* Move volume ray forward. */
+ volume_ray.P = P;
+ }
+#endif
+
#if defined(__EMISSION__) && defined(__BRANCHED_PATH__)
/* direct light */
if(kernel_data.integrator.use_direct_light) {
@@ -783,7 +871,12 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
path_radiance_init(&L, kernel_data.film.use_light_pass);
PathState state;
- path_state_init(kg, &state, rng, sample);
+ path_state_init(kg, &state, rng, sample, &ray);
+
+#ifdef __KERNEL_DEBUG__
+ DebugData debug_data;
+ debug_data_init(&debug_data);
+#endif
for(;;) {
/* intersect scene */
@@ -807,7 +900,13 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
bool hit = scene_intersect(kg, &ray, visibility, &isect, &lcg_state, difl, extmax);
#else
- bool hit = scene_intersect(kg, &ray, visibility, &isect);
+ bool hit = scene_intersect(kg, &ray, visibility, &isect, NULL, 0.0f, 0.0f);
+#endif
+
+#ifdef __KERNEL_DEBUG__
+ if(state.flag & PATH_RAY_CAMERA) {
+ debug_data.num_bvh_traversal_steps += isect.num_traversal_steps;
+ }
#endif
#ifdef __VOLUME__
@@ -1016,7 +1115,8 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
#ifdef __SUBSURFACE__
/* bssrdf scatter to a different location on the same object */
if(sd.flag & SD_BSSRDF) {
- kernel_branched_path_subsurface_scatter(kg, &sd, &L, &state, rng, throughput);
+ kernel_branched_path_subsurface_scatter(kg, &sd, &L, &state,
+ rng, &ray, throughput);
}
#endif
@@ -1064,6 +1164,10 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
kernel_write_light_passes(kg, buffer, &L, sample);
+#ifdef __KERNEL_DEBUG__
+ kernel_write_debug_passes(kg, buffer, &state, &debug_data, sample);
+#endif
+
return make_float4(L_sum.x, L_sum.y, L_sum.z, 1.0f - L_transparent);
}
diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h
index 43e75885849..f29168642a4 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -16,7 +16,7 @@
CCL_NAMESPACE_BEGIN
-ccl_device_inline void path_state_init(KernelGlobals *kg, PathState *state, RNG *rng, int sample)
+ccl_device_inline void path_state_init(KernelGlobals *kg, PathState *state, RNG *rng, int sample, Ray *ray)
{
state->flag = PATH_RAY_CAMERA|PATH_RAY_MIS_SKIP;
@@ -41,7 +41,7 @@ ccl_device_inline void path_state_init(KernelGlobals *kg, PathState *state, RNG
if(kernel_data.integrator.use_volumes) {
/* initialize volume stack with volume we are inside of */
- kernel_volume_stack_init(kg, state->volume_stack);
+ kernel_volume_stack_init(kg, ray, state->volume_stack);
/* seed RNG for cases where we can't use stratified samples */
state->rng_congruential = lcg_init(*rng + sample*0x51633e2d);
}
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index fc61f1a9c2c..db08c328d7e 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -87,7 +87,7 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
if(sd->type & PRIMITIVE_TRIANGLE) {
/* static triangle */
float3 Ng = triangle_normal(kg, sd);
- sd->shader = __float_as_int(kernel_tex_fetch(__tri_shader, sd->prim));
+ sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
/* vectors */
sd->P = triangle_refine(kg, sd, isect, ray);
@@ -166,7 +166,7 @@ ccl_device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderDat
/* fetch triangle data */
if(sd->type == PRIMITIVE_TRIANGLE) {
float3 Ng = triangle_normal(kg, sd);
- sd->shader = __float_as_int(kernel_tex_fetch(__tri_shader, sd->prim));
+ sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
/* static triangle */
sd->P = triangle_refine_subsurface(kg, sd, isect, ray);
@@ -798,8 +798,8 @@ ccl_device void shader_eval_surface(KernelGlobals *kg, ShaderData *sd,
#ifdef __SVM__
svm_eval_nodes(kg, sd, SHADER_TYPE_SURFACE, path_flag);
#else
- sd->closure.weight = make_float3(0.8f, 0.8f, 0.8f);
- sd->closure.N = sd->N;
+ sd->closure->weight = make_float3(0.8f, 0.8f, 0.8f);
+ sd->closure->N = sd->N;
sd->flag |= bsdf_diffuse_setup(&sd->closure);
#endif
}
@@ -1026,7 +1026,7 @@ ccl_device bool shader_transparent_shadow(KernelGlobals *kg, Intersection *isect
#ifdef __HAIR__
if(kernel_tex_fetch(__prim_type, isect->prim) & PRIMITIVE_ALL_TRIANGLE) {
#endif
- shader = __float_as_int(kernel_tex_fetch(__tri_shader, prim));
+ shader = kernel_tex_fetch(__tri_shader, prim);
#ifdef __HAIR__
}
else {
diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h
index 439e8bbd585..61954282c28 100644
--- a/intern/cycles/kernel/kernel_shadow.h
+++ b/intern/cycles/kernel/kernel_shadow.h
@@ -168,11 +168,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
}
else {
Intersection isect;
-#ifdef __HAIR__
blocked = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f);
-#else
- blocked = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect);
-#endif
}
#ifdef __VOLUME__
@@ -185,6 +181,8 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
return blocked;
}
+#undef STACK_MAX_HITS
+
#else
/* Shadow function to compute how much light is blocked, GPU variation.
@@ -203,11 +201,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
return false;
Intersection isect;
-#ifdef __HAIR__
bool blocked = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect, NULL, 0.0f, 0.0f);
-#else
- bool blocked = scene_intersect(kg, ray, PATH_RAY_SHADOW_OPAQUE, &isect);
-#endif
#ifdef __TRANSPARENT_SHADOWS__
if(blocked && kernel_data.integrator.transparent_shadows) {
@@ -223,11 +217,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg, PathState *state, Ray *
if(bounce >= kernel_data.integrator.transparent_max_bounce)
return true;
-#ifdef __HAIR__
if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, &isect, NULL, 0.0f, 0.0f))
-#else
- if(!scene_intersect(kg, ray, PATH_RAY_SHADOW_TRANSPARENT, &isect))
-#endif
{
#ifdef __VOLUME__
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index f60ed8ccd07..ef46b2f707f 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -36,7 +36,7 @@ KERNEL_TEX(float4, texture_float4, __objects)
KERNEL_TEX(float4, texture_float4, __objects_vector)
/* triangles */
-KERNEL_TEX(float, texture_float, __tri_shader)
+KERNEL_TEX(uint, texture_uint, __tri_shader)
KERNEL_TEX(float4, texture_float4, __tri_vnormal)
KERNEL_TEX(float4, texture_float4, __tri_vindex)
KERNEL_TEX(float4, texture_float4, __tri_verts)
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 1f01622e349..e5cd23c0925 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -157,6 +157,10 @@ CCL_NAMESPACE_BEGIN
#define __HAIR__
#endif
+#ifdef WITH_CYCLES_DEBUG
+# define __KERNEL_DEBUG__
+#endif
+
/* Random Numbers */
typedef uint RNG;
@@ -313,6 +317,9 @@ typedef enum PassType {
PASS_SUBSURFACE_INDIRECT = 8388608,
PASS_SUBSURFACE_COLOR = 16777216,
PASS_LIGHT = 33554432, /* no real pass, used to force use_light_pass */
+#ifdef __KERNEL_DEBUG__
+ PASS_BVH_TRAVERSAL_STEPS = 67108864,
+#endif
} PassType;
#define PASS_ALL (~0)
@@ -453,6 +460,10 @@ typedef struct Intersection {
int prim;
int object;
int type;
+
+#ifdef __KERNEL_DEBUG__
+ int num_traversal_steps;
+#endif
} Intersection;
/* Primitives */
@@ -530,7 +541,7 @@ typedef enum AttributeStandard {
/* TODO(sergey): This is rather nasty bug happening in here, which
* could be simply a compilers bug for which we can't find a generic
- * platform indipendent workaround. Also even if it's a compiler
+ * platform independent workaround. Also even if it's a compiler
* issue, it's not so simple to upgrade the compiler in the release
* environment for linux and doing it so closer to the release is
* rather a risky business.
@@ -615,8 +626,12 @@ enum ShaderDataFlag {
SD_OBJECT_MOTION = 1048576, /* has object motion blur */
SD_TRANSFORM_APPLIED = 2097152, /* vertices have transform applied */
SD_NEGATIVE_SCALE_APPLIED = 4194304, /* vertices have negative scale applied */
+ SD_OBJECT_HAS_VOLUME = 8388608, /* object has a volume shader */
+ SD_OBJECT_INTERSECTS_VOLUME = 16777216, /* object intersects AABB of an object with volume shader */
- SD_OBJECT_FLAGS = (SD_HOLDOUT_MASK|SD_OBJECT_MOTION|SD_TRANSFORM_APPLIED)
+ SD_OBJECT_FLAGS = (SD_HOLDOUT_MASK|SD_OBJECT_MOTION|SD_TRANSFORM_APPLIED|
+ SD_NEGATIVE_SCALE_APPLIED|SD_OBJECT_HAS_VOLUME|
+ SD_OBJECT_INTERSECTS_VOLUME)
};
struct KernelGlobals;
@@ -784,7 +799,7 @@ typedef struct KernelCamera {
/* anamorphic lens bokeh */
float inv_aperture_ratio;
- int pad1;
+ int is_inside_volume;
int pad2;
/* more matrices */
@@ -846,6 +861,11 @@ typedef struct KernelFilm {
float mist_start;
float mist_inv_depth;
float mist_falloff;
+
+#ifdef __KERNEL_DEBUG__
+ int pass_bvh_traversal_steps;
+ int pass_pad3, pass_pad4, pass_pad5;
+#endif
} KernelFilm;
typedef struct KernelBackground {
@@ -972,6 +992,14 @@ typedef struct KernelData {
KernelTables tables;
} KernelData;
+#ifdef __KERNEL_DEBUG__
+typedef struct DebugData {
+ // Total number of BVH node travesal steps and primitives intersections
+ // for the camera rays.
+ int num_bvh_traversal_steps;
+} DebugData;
+#endif
+
CCL_NAMESPACE_END
#endif /* __KERNEL_TYPES_H__ */
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index ea02ede10cd..93cb4c120ea 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -954,17 +954,88 @@ ccl_device bool kernel_volume_use_decoupled(KernelGlobals *kg, bool heterogeneou
* This is an array of object/shared ID's that the current segment of the path
* is inside of. */
-ccl_device void kernel_volume_stack_init(KernelGlobals *kg, VolumeStack *stack)
+ccl_device void kernel_volume_stack_init(KernelGlobals *kg,
+ Ray *ray,
+ VolumeStack *stack)
{
- /* todo: this assumes camera is always in air, need to detect when it isn't */
- if(kernel_data.background.volume_shader == SHADER_NONE) {
- stack[0].shader = SHADER_NONE;
+ /* NULL ray happens in the baker, does it need proper initializetion of
+ * camera in volume?
+ */
+ if(!kernel_data.cam.is_inside_volume || ray == NULL) {
+ /* Camera is guaranteed to be in the air, only take background volume
+ * into account in this case.
+ */
+ if(kernel_data.background.volume_shader != SHADER_NONE) {
+ stack[0].shader = kernel_data.background.volume_shader;
+ stack[0].object = PRIM_NONE;
+ stack[1].shader = SHADER_NONE;
+ }
+ else {
+ stack[0].shader = SHADER_NONE;
+ }
+ return;
}
- else {
+
+ Ray volume_ray = *ray;
+ volume_ray.t = FLT_MAX;
+
+ int stack_index = 0, enclosed_index = 0;
+ int enclosed_volumes[VOLUME_STACK_SIZE];
+
+ while(stack_index < VOLUME_STACK_SIZE - 1 &&
+ enclosed_index < VOLUME_STACK_SIZE - 1)
+ {
+ Intersection isect;
+ if(!scene_intersect_volume(kg, &volume_ray, &isect)) {
+ break;
+ }
+
+ ShaderData sd;
+ shader_setup_from_ray(kg, &sd, &isect, &volume_ray, 0, 0);
+ if(sd.flag & SD_HAS_VOLUME) {
+ if(sd.flag & SD_BACKFACING) {
+ /* If ray exited the volume and never entered to that volume
+ * it means that camera is inside such a volume.
+ */
+ bool is_enclosed = false;
+ for(int i = 0; i < enclosed_index; ++i) {
+ if(enclosed_volumes[i] == sd.object) {
+ is_enclosed = true;
+ break;
+ }
+ }
+ if(is_enclosed == false) {
+ stack[stack_index].object = sd.object;
+ stack[stack_index].shader = sd.shader;
+ ++stack_index;
+ }
+ }
+ else {
+ /* If ray from camera enters the volume, this volume shouldn't
+ * be added to the stak on exit.
+ */
+ enclosed_volumes[enclosed_index++] = sd.object;
+ }
+ }
+
+ /* Move ray forward. */
+ volume_ray.P = ray_offset(sd.P, -sd.Ng);
+ }
+ /* stack_index of 0 means quick checks outside of the kernel gave false
+ * positive, nothing to worry about, just we've wasted quite a few of
+ * ticks just to come into conclusion that camera is in the air.
+ *
+ * In this case we're doing the same above -- check whether background has
+ * volume.
+ */
+ if(stack_index == 0 && kernel_data.background.volume_shader == SHADER_NONE) {
stack[0].shader = kernel_data.background.volume_shader;
stack[0].object = PRIM_NONE;
stack[1].shader = SHADER_NONE;
}
+ else {
+ stack[stack_index].shader = SHADER_NONE;
+ }
}
ccl_device void kernel_volume_stack_enter_exit(KernelGlobals *kg, ShaderData *sd, VolumeStack *stack)
@@ -1013,4 +1084,3 @@ ccl_device void kernel_volume_stack_enter_exit(KernelGlobals *kg, ShaderData *sd
}
CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/SConscript b/intern/cycles/kernel/osl/SConscript
index 4685bb7753e..d721edbaf6e 100644
--- a/intern/cycles/kernel/osl/SConscript
+++ b/intern/cycles/kernel/osl/SConscript
@@ -43,6 +43,9 @@ defs.append('CCL_NAMESPACE_BEGIN=namespace ccl {')
defs.append('CCL_NAMESPACE_END=}')
defs.append('WITH_OSL')
+if env['WITH_BF_CYCLES_DEBUG']:
+ defs.append('WITH_CYCLES_DEBUG')
+
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
cxxflags.append('-DBOOST_NO_RTTI -DBOOST_NO_TYPEID /fp:fast'.split())
incs.append(env['BF_PTHREADS_INC'])
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index d7789edcfff..cc9942b024e 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -54,7 +54,6 @@
#include "closure/bsdf_refraction.h"
#include "closure/bsdf_transparent.h"
#include "closure/bsdf_ashikhmin_shirley.h"
-#include "closure/bsdf_westin.h"
#include "closure/bsdf_toon.h"
#include "closure/bsdf_hair.h"
#include "closure/volume.h"
@@ -87,16 +86,6 @@ BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, refraction, LABEL_SINGULAR)
CLOSURE_FLOAT_PARAM(RefractionClosure, sc.data0),
BSDF_CLOSURE_CLASS_END(Refraction, refraction)
-BSDF_CLOSURE_CLASS_BEGIN(WestinBackscatter, westin_backscatter, westin_backscatter, LABEL_GLOSSY)
- CLOSURE_FLOAT3_PARAM(WestinBackscatterClosure, sc.N),
- CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, sc.data0),
-BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter)
-
-BSDF_CLOSURE_CLASS_BEGIN(WestinSheen, westin_sheen, westin_sheen, LABEL_DIFFUSE)
- CLOSURE_FLOAT3_PARAM(WestinSheenClosure, sc.N),
- CLOSURE_FLOAT_PARAM(WestinSheenClosure, sc.data0),
-BSDF_CLOSURE_CLASS_END(WestinSheen, westin_sheen)
-
BSDF_CLOSURE_CLASS_BEGIN(Transparent, transparent, transparent, LABEL_SINGULAR)
BSDF_CLOSURE_CLASS_END(Transparent, transparent)
@@ -244,10 +233,6 @@ void OSLShader::register_closures(OSLShadingSystem *ss_)
bsdf_diffuse_toon_params(), bsdf_diffuse_toon_prepare);
register_closure(ss, "glossy_toon", id++,
bsdf_glossy_toon_params(), bsdf_glossy_toon_prepare);
- register_closure(ss, "westin_backscatter", id++,
- bsdf_westin_backscatter_params(), bsdf_westin_backscatter_prepare);
- register_closure(ss, "westin_sheen", id++,
- bsdf_westin_sheen_params(), bsdf_westin_sheen_prepare);
register_closure(ss, "emission", id++,
closure_emission_params(), closure_emission_prepare);
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index 58d215295dc..5e833d738d8 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -48,8 +48,6 @@ OSL::ClosureParam *closure_holdout_params();
OSL::ClosureParam *closure_ambient_occlusion_params();
OSL::ClosureParam *closure_bsdf_diffuse_ramp_params();
OSL::ClosureParam *closure_bsdf_phong_ramp_params();
-OSL::ClosureParam *closure_westin_backscatter_params();
-OSL::ClosureParam *closure_westin_sheen_params();
OSL::ClosureParam *closure_bssrdf_cubic_params();
OSL::ClosureParam *closure_bssrdf_gaussian_params();
OSL::ClosureParam *closure_henyey_greenstein_volume_params();
@@ -60,8 +58,6 @@ void closure_holdout_prepare(OSL::RendererServices *, int id, void *data);
void closure_ambient_occlusion_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_diffuse_ramp_prepare(OSL::RendererServices *, int id, void *data);
void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
-void closure_westin_backscatter_prepare(OSL::RendererServices *, int id, void *data);
-void closure_westin_sheen_prepare(OSL::RendererServices *, int id, void *data);
void closure_bssrdf_cubic_prepare(OSL::RendererServices *, int id, void *data);
void closure_bssrdf_gaussian_prepare(OSL::RendererServices *, int id, void *data);
void closure_henyey_greenstein_volume_prepare(OSL::RendererServices *, int id, void *data);
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 5a658d8244a..9c3134e41c9 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -20,7 +20,6 @@
#ifdef WITH_OSL
#include <OSL/oslexec.h>
-#include <cmath>
#include "util_map.h"
#include "util_param.h"
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index 38cb5061346..1475e5a0a62 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -1047,11 +1047,7 @@ bool OSLRenderServices::trace(TraceOpt &options, OSL::ShaderGlobals *sg,
tracedata->sd.osl_globals = sd->osl_globals;
/* raytrace */
-#ifdef __HAIR__
return scene_intersect(sd->osl_globals, &ray, PATH_RAY_ALL_VISIBILITY, &tracedata->isect, NULL, 0.0f, 0.0f);
-#else
- return scene_intersect(sd->osl_globals, &ray, PATH_RAY_ALL_VISIBILITY, &tracedata->isect);
-#endif
}
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index 48498116874..ca0c2cc4415 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -14,6 +14,8 @@
* limitations under the License
*/
+#include <OSL/oslexec.h>
+
#include "kernel_compat_cpu.h"
#include "kernel_montecarlo.h"
#include "kernel_types.h"
@@ -34,7 +36,6 @@
#include "attribute.h"
-#include <OSL/oslexec.h>
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/kernel/shaders/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl
index 70a6a6ea7ce..c9fb3542aef 100644
--- a/intern/cycles/kernel/shaders/node_brick_texture.osl
+++ b/intern/cycles/kernel/shaders/node_brick_texture.osl
@@ -93,6 +93,6 @@ shader node_brick_texture(
Col[2] = facm * (Color1[2]) + tint * Color2[2];
}
- Color = (Fac == 1.0) ? Mortar: Col;
+ Color = (Fac == 1.0) ? Mortar : Col;
}
diff --git a/intern/cycles/kernel/shaders/node_fresnel.h b/intern/cycles/kernel/shaders/node_fresnel.h
index 9f10ba8023e..d192c5d02de 100644
--- a/intern/cycles/kernel/shaders/node_fresnel.h
+++ b/intern/cycles/kernel/shaders/node_fresnel.h
@@ -36,14 +36,14 @@ float fresnel_dielectric_cos(float cosi, float eta)
color fresnel_conductor(float cosi, color eta, color k)
{
- color cosi2 = color(cosi*cosi);
+ color cosi2 = color(cosi * cosi);
color one = color(1, 1, 1);
color tmp_f = eta * eta + k * k;
color tmp = tmp_f * cosi2;
color Rparl2 = (tmp - (2.0 * eta * cosi) + one) /
- (tmp + (2.0 * eta * cosi) + one);
+ (tmp + (2.0 * eta * cosi) + one);
color Rperp2 = (tmp_f - (2.0 * eta * cosi) + cosi2) /
- (tmp_f + (2.0 * eta * cosi) + cosi2);
+ (tmp_f + (2.0 * eta * cosi) + cosi2);
return (Rparl2 + Rperp2) * 0.5;
}
diff --git a/intern/cycles/kernel/shaders/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl
index 7bef2051865..cd68f07b21e 100644
--- a/intern/cycles/kernel/shaders/node_geometry.osl
+++ b/intern/cycles/kernel/shaders/node_geometry.osl
@@ -49,7 +49,7 @@ shader node_geometry(
/* try to create spherical tangent from generated coordinates */
if (getattribute("geom:generated", generated)) {
- normal data = normal(-(generated[1]-0.5), (generated[0]-0.5), 0.0);
+ normal data = normal(-(generated[1] - 0.5), (generated[0] - 0.5), 0.0);
vector T = transform("object", "world", data);
Tangent = cross(Normal, normalize(cross(T, Normal)));
}
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl
index 7238a1e8862..18b5fb4b31f 100644
--- a/intern/cycles/kernel/shaders/node_image_texture.osl
+++ b/intern/cycles/kernel/shaders/node_image_texture.osl
@@ -113,6 +113,10 @@ shader node_image_texture(
weight[2] = ((2.0 - limit) * Nob[2] + (limit - 1.0)) / (2.0 * limit - 1.0);
}
}
+ else {
+ /* Desperate mode, no valid choice anyway, fallback to one side.*/
+ weight[0] = 1.0;
+ }
Color = color(0.0, 0.0, 0.0);
Alpha = 0.0;
diff --git a/intern/cycles/kernel/shaders/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
index 60762539002..a32c3d4b1b8 100644
--- a/intern/cycles/kernel/shaders/node_musgrave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
@@ -35,14 +35,14 @@ float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float
int i;
for (i = 0; i < (int)octaves; i++) {
- value += safe_noise(p, 0) * pwr;
+ value += safe_noise(p, "signed") * pwr;
pwr *= pwHL;
p *= lacunarity;
}
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- value += rmd * safe_noise(p, 0) * pwr;
+ value += rmd * safe_noise(p, "signed") * pwr;
return value;
}
@@ -63,14 +63,14 @@ float noise_musgrave_multi_fractal(point p, string basis, float H, float lacunar
int i;
for (i = 0; i < (int)octaves; i++) {
- value *= (pwr * safe_noise(p, 0) + 1.0);
+ value *= (pwr * safe_noise(p, "signed") + 1.0);
pwr *= pwHL;
p *= lacunarity;
}
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- value *= (rmd * pwr * safe_noise(p, 0) + 1.0); /* correct? */
+ value *= (rmd * pwr * safe_noise(p, "signed") + 1.0); /* correct? */
return value;
}
@@ -91,11 +91,11 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
int i;
/* first unscaled octave of function; later octaves are scaled */
- value = offset + safe_noise(p, 0);
+ value = offset + safe_noise(p, "signed");
p *= lacunarity;
for (i = 1; i < (int)octaves; i++) {
- increment = (safe_noise(p, 0) + offset) * pwr * value;
+ increment = (safe_noise(p, "signed") + offset) * pwr * value;
value += increment;
pwr *= pwHL;
p *= lacunarity;
@@ -103,7 +103,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
rmd = octaves - floor(octaves);
if (rmd != 0.0) {
- increment = (safe_noise(p, 0) + offset) * pwr * value;
+ increment = (safe_noise(p, "signed") + offset) * pwr * value;
value += rmd * increment;
}
@@ -126,7 +126,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
float pwr = pwHL;
int i;
- result = safe_noise(p, 0) + offset;
+ result = safe_noise(p, "signed") + offset;
weight = gain * result;
p *= lacunarity;
@@ -134,7 +134,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
if (weight > 1.0)
weight = 1.0;
- signal = (safe_noise(p, 0) + offset) * pwr;
+ signal = (safe_noise(p, "signed") + offset) * pwr;
pwr *= pwHL;
result += weight * signal;
weight *= gain * signal;
@@ -143,7 +143,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
rmd = octaves - floor(octaves);
if (rmd != 0.0)
- result += rmd * ((safe_noise(p, 0) + offset) * pwr);
+ result += rmd * ((safe_noise(p, "signed") + offset) * pwr);
return result;
}
@@ -164,7 +164,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H,
float pwr = pwHL;
int i;
- signal = offset - fabs(safe_noise(p, 0));
+ signal = offset - fabs(safe_noise(p, "signed"));
signal *= signal;
result = signal;
weight = 1.0;
@@ -172,7 +172,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H,
for (i = 1; i < (int)octaves; i++) {
p *= lacunarity;
weight = clamp(signal * gain, 0.0, 1.0);
- signal = offset - fabs(safe_noise(p, 0));
+ signal = offset - fabs(safe_noise(p, "signed"));
signal *= signal;
signal *= weight;
result += signal * pwr;
diff --git a/intern/cycles/kernel/shaders/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h
index de51559f297..2710eed414a 100644
--- a/intern/cycles/kernel/shaders/node_texture.h
+++ b/intern/cycles/kernel/shaders/node_texture.h
@@ -153,12 +153,12 @@ float voronoi_CrS(point p) { return 2.0 * voronoi_Cr(p) - 1.0; }
/* Noise Bases */
-float safe_noise(point p, int type)
+float safe_noise(point p, string type)
{
float f = 0.0;
/* Perlin noise in range -1..1 */
- if (type == 0)
+ if (type == "signed")
f = noise("perlin", p);
/* Perlin noise in range 0..1 */
@@ -175,7 +175,7 @@ float safe_noise(point p, int type)
float noise_basis(point p, string basis)
{
if (basis == "Perlin")
- return safe_noise(p, 1);
+ return safe_noise(p, "unsigned");
if (basis == "Voronoi F1")
return voronoi_F1S(p);
if (basis == "Voronoi F2")
diff --git a/intern/cycles/kernel/shaders/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index f8e5fd510ee..1ff8f363b49 100644
--- a/intern/cycles/kernel/shaders/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -476,8 +476,6 @@ closure color diffuse_ramp(normal N, color colors[8]) BUILTIN;
closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
closure color diffuse_toon(normal N, float size, float smooth) BUILTIN;
closure color glossy_toon(normal N, float size, float smooth) BUILTIN;
-closure color westin_backscatter(normal N, float roughness) BUILTIN;
-closure color westin_sheen(normal N, float edginess) BUILTIN;
closure color translucent(normal N) BUILTIN;
closure color reflection(normal N) BUILTIN;
closure color refraction(normal N, float eta) BUILTIN;
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index a7abeda18e5..8a256c9bda5 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -435,6 +435,10 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float
weight.z = ((2.0f - limit)*N.z + (limit - 1.0f))/(2.0f*limit - 1.0f);
}
}
+ else {
+ /* Desperate mode, no valid choice anyway, fallback to one side.*/
+ weight.x = 1.0f;
+ }
/* now fetch textures */
uint co_offset, out_offset, alpha_offset, srgb;
diff --git a/intern/cycles/kernel/svm/svm_noise.h b/intern/cycles/kernel/svm/svm_noise.h
index 869341c81f4..c77c2a1c482 100644
--- a/intern/cycles/kernel/svm/svm_noise.h
+++ b/intern/cycles/kernel/svm/svm_noise.h
@@ -290,40 +290,6 @@ ccl_device_noinline float perlin(float x, float y, float z)
}
#endif
-#if 0 // unused
-ccl_device_noinline float perlin_periodic(float x, float y, float z, float3 pperiod)
-{
- int X; float fx = floorfrac(x, &X);
- int Y; float fy = floorfrac(y, &Y);
- int Z; float fz = floorfrac(z, &Z);
-
- int3 p;
-
- p.x = max(quick_floor(pperiod.x), 1);
- p.y = max(quick_floor(pperiod.y), 1);
- p.z = max(quick_floor(pperiod.z), 1);
-
- float u = fade(fx);
- float v = fade(fy);
- float w = fade(fz);
-
- float result;
-
- result = nerp (w, nerp (v, nerp (u, grad (phash (X , Y , Z , p), fx , fy , fz ),
- grad (phash (X+1, Y , Z , p), fx-1.0f, fy , fz )),
- nerp (u, grad (phash (X , Y+1, Z , p), fx , fy-1.0f, fz ),
- grad (phash (X+1, Y+1, Z , p), fx-1.0f, fy-1.0f, fz ))),
- nerp (v, nerp (u, grad (phash (X , Y , Z+1, p), fx , fy , fz-1.0f ),
- grad (phash (X+1, Y , Z+1, p), fx-1.0f, fy , fz-1.0f )),
- nerp (u, grad (phash (X , Y+1, Z+1, p), fx , fy-1.0f, fz-1.0f ),
- grad (phash (X+1, Y+1, Z+1, p), fx-1.0f, fy-1.0f, fz-1.0f ))));
- float r = scale3(result);
-
- /* can happen for big coordinates, things even out to 0.0 then anyway */
- return (isfinite(r))? r: 0.0f;
-}
-#endif
-
/* perlin noise in range 0..1 */
ccl_device float noise(float3 p)
{
@@ -367,20 +333,5 @@ ccl_device ssef cellnoise_color(const ssef& p)
}
#endif
-#if 0 // unused
-/* periodic perlin noise in range 0..1 */
-ccl_device float pnoise(float3 p, float3 pperiod)
-{
- float r = perlin_periodic(p.x, p.y, p.z, pperiod);
- return 0.5f*r + 0.5f;
-}
-
-/* periodic perlin noise in range -1..1 */
-ccl_device float psnoise(float3 p, float3 pperiod)
-{
- return perlin_periodic(p.x, p.y, p.z, pperiod);
-}
-#endif
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 103f562ed60..fbe669c1fab 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -348,7 +348,6 @@ typedef enum ClosureType {
/* Diffuse */
CLOSURE_BSDF_DIFFUSE_ID,
CLOSURE_BSDF_OREN_NAYAR_ID,
- CLOSURE_BSDF_WESTIN_SHEEN_ID,
CLOSURE_BSDF_DIFFUSE_RAMP_ID,
CLOSURE_BSDF_DIFFUSE_TOON_ID,
@@ -362,7 +361,6 @@ typedef enum ClosureType {
CLOSURE_BSDF_MICROFACET_BECKMANN_ANISO_ID,
CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ANISO_ID,
CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
- CLOSURE_BSDF_WESTIN_BACKSCATTER_ID,
CLOSURE_BSDF_PHONG_RAMP_ID,
CLOSURE_BSDF_GLOSSY_TOON_ID,
CLOSURE_BSDF_HAIR_REFLECTION_ID,
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index fc65922fc87..756e16b38b5 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -190,6 +190,14 @@ bool RenderBuffers::get_pass_rect(PassType type, float exposure, int sample, int
pixels[0] = clamp(f*scale_exposure, 0.0f, 1.0f);
}
}
+#ifdef WITH_CYCLES_DEBUG
+ else if(type == PASS_BVH_TRAVERSAL_STEPS) {
+ for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
+ float f = *in;
+ pixels[0] = f;
+ }
+ }
+#endif
else {
for(int i = 0; i < size; i++, in += pass_stride, pixels++) {
float f = *in;
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index bb0fec759a9..110adb4d036 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -15,10 +15,13 @@
*/
#include "camera.h"
+#include "mesh.h"
+#include "object.h"
#include "scene.h"
#include "device.h"
+#include "util_foreach.h"
#include "util_vector.h"
CCL_NAMESPACE_BEGIN
@@ -270,6 +273,20 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
need_device_update = false;
previous_need_motion = need_motion;
+
+ /* Camera in volume. */
+ kcam->is_inside_volume = 0;
+ BoundBox viewplane_boundbox = viewplane_bounds_get();
+ for(size_t i = 0; i < scene->objects.size(); ++i) {
+ Object *object = scene->objects[i];
+ if(object->mesh->has_volume &&
+ viewplane_boundbox.intersects(object->bounds))
+ {
+ /* TODO(sergey): Consider adding more grained check. */
+ kcam->is_inside_volume = 1;
+ break;
+ }
+ }
}
void Camera::device_free(Device *device, DeviceScene *dscene)
@@ -313,5 +330,62 @@ void Camera::tag_update()
need_update = true;
}
+float3 Camera::transform_raster_to_world(float raster_x, float raster_y)
+{
+ float3 D, P;
+ if(type == CAMERA_PERSPECTIVE) {
+ D = transform_perspective(&rastertocamera,
+ make_float3(raster_x, raster_y, 0.0f));
+ P = make_float3(0.0f, 0.0f, 0.0f);
+ /* TODO(sergey): Aperture support? */
+ P = transform_point(&cameratoworld, P);
+ D = normalize(transform_direction(&cameratoworld, D));
+ /* TODO(sergey): Clipping is conditional in kernel, and hence it could
+ * be mistakes in here, currently leading to wrong camera-in-volume
+ * detection.
+ */
+ P += nearclip * D;
+ }
+ else if (type == CAMERA_ORTHOGRAPHIC) {
+ D = make_float3(0.0f, 0.0f, 1.0f);
+ /* TODO(sergey): Aperture support? */
+ P = transform_perspective(&rastertocamera,
+ make_float3(raster_x, raster_y, 0.0f));
+ P = transform_point(&cameratoworld, P);
+ D = normalize(transform_direction(&cameratoworld, D));
+ }
+ else {
+ assert(!"unsupported camera type");
+ }
+ return P;
+}
+
+BoundBox Camera::viewplane_bounds_get()
+{
+ /* TODO(sergey): This is all rather stupid, but is there a way to perform
+ * checks we need in a more clear and smart fasion?
+ */
+ BoundBox bounds = BoundBox::empty;
+
+ if(type == CAMERA_PANORAMA) {
+ bounds.grow(make_float3(cameratoworld.w.x,
+ cameratoworld.w.y,
+ cameratoworld.w.z));
+ }
+ else {
+ bounds.grow(transform_raster_to_world(0.0f, 0.0f));
+ bounds.grow(transform_raster_to_world(0.0f, (float)height));
+ bounds.grow(transform_raster_to_world((float)width, (float)height));
+ bounds.grow(transform_raster_to_world((float)width, 0.0f));
+ if(type == CAMERA_PERSPECTIVE) {
+ /* Center point has the most distancei in local Z axis,
+ * use it to construct bounding box/
+ */
+ bounds.grow(transform_raster_to_world(0.5f*width, 0.5f*height));
+ }
+ }
+ return bounds;
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 50889968a90..788ae7b9bb6 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -116,6 +116,9 @@ public:
bool modified(const Camera& cam);
bool motion_modified(const Camera& cam);
void tag_update();
+
+ BoundBox viewplane_bounds_get();
+ float3 transform_raster_to_world(float raster_x, float raster_y);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/film.cpp b/intern/cycles/render/film.cpp
index 09973e8bc86..19f959d4ea1 100644
--- a/intern/cycles/render/film.cpp
+++ b/intern/cycles/render/film.cpp
@@ -146,6 +146,12 @@ void Pass::add(PassType type, vector<Pass>& passes)
case PASS_LIGHT:
/* ignores */
break;
+#ifdef WITH_CYCLES_DEBUG
+ case PASS_BVH_TRAVERSAL_STEPS:
+ pass.components = 1;
+ pass.exposure = false;
+ break;
+#endif
}
passes.push_back(pass);
@@ -388,6 +394,13 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
case PASS_LIGHT:
kfilm->use_light_pass = 1;
break;
+
+#ifdef WITH_CYCLES_DEBUG
+ case PASS_BVH_TRAVERSAL_STEPS:
+ kfilm->pass_bvh_traversal_steps = kfilm->pass_stride;
+ break;
+#endif
+
case PASS_NONE:
break;
}
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 0ff904d06e7..45b08832fea 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -320,20 +320,20 @@ void ShaderGraph::remove_unneeded_nodes()
{
vector<bool> removed(num_node_ids, false);
bool any_node_removed = false;
-
+
/* find and unlink proxy nodes */
foreach(ShaderNode *node, nodes) {
if(node->special_type == SHADER_SPECIAL_TYPE_PROXY) {
ProxyNode *proxy = static_cast<ProxyNode*>(node);
ShaderInput *input = proxy->inputs[0];
ShaderOutput *output = proxy->outputs[0];
-
+
/* temp. copy of the output links list.
* output->links is modified when we disconnect!
*/
vector<ShaderInput*> links(output->links);
ShaderOutput *from = input->link;
-
+
/* bypass the proxy node */
if(from) {
disconnect(input);
@@ -391,6 +391,8 @@ void ShaderGraph::remove_unneeded_nodes()
if(output)
connect(output, input);
}
+ removed[mix->id] = true;
+ any_node_removed = true;
}
/* remove unused mix closure input when factor is 0.0 or 1.0 */
@@ -400,7 +402,7 @@ void ShaderGraph::remove_unneeded_nodes()
if(mix->inputs[0]->value.x == 0.0f) {
ShaderOutput *output = mix->inputs[1]->link;
vector<ShaderInput*> inputs = mix->outputs[0]->links;
-
+
foreach(ShaderInput *sock, mix->inputs)
if(sock->link)
disconnect(sock);
@@ -410,6 +412,8 @@ void ShaderGraph::remove_unneeded_nodes()
if(output)
connect(output, input);
}
+ removed[mix->id] = true;
+ any_node_removed = true;
}
/* factor 1.0 */
else if(mix->inputs[0]->value.x == 1.0f) {
@@ -425,13 +429,57 @@ void ShaderGraph::remove_unneeded_nodes()
if(output)
connect(output, input);
}
+ removed[mix->id] = true;
+ any_node_removed = true;
+ }
+ }
+ }
+ else if(node->special_type == SHADER_SPECIAL_TYPE_MIX_RGB) {
+ MixNode *mix = static_cast<MixNode*>(node);
+
+ /* remove unused Mix RGB inputs when factor is 0.0 or 1.0 */
+ /* check for color links and make sure factor link is disconnected */
+ if(mix->outputs[0]->links.size() && mix->inputs[1]->link && mix->inputs[2]->link && !mix->inputs[0]->link) {
+ /* factor 0.0 */
+ if(mix->inputs[0]->value.x == 0.0f) {
+ ShaderOutput *output = mix->inputs[1]->link;
+ vector<ShaderInput*> inputs = mix->outputs[0]->links;
+
+ foreach(ShaderInput *sock, mix->inputs)
+ if(sock->link)
+ disconnect(sock);
+
+ foreach(ShaderInput *input, inputs) {
+ disconnect(input);
+ if(output)
+ connect(output, input);
+ }
+ removed[mix->id] = true;
+ any_node_removed = true;
+ }
+ /* factor 1.0 */
+ else if(mix->inputs[0]->value.x == 1.0f) {
+ ShaderOutput *output = mix->inputs[2]->link;
+ vector<ShaderInput*> inputs = mix->outputs[0]->links;
+
+ foreach(ShaderInput *sock, mix->inputs)
+ if(sock->link)
+ disconnect(sock);
+
+ foreach(ShaderInput *input, inputs) {
+ disconnect(input);
+ if(output)
+ connect(output, input);
+ }
+ removed[mix->id] = true;
+ any_node_removed = true;
}
}
}
}
/* remove nodes */
- if (any_node_removed) {
+ if(any_node_removed) {
list<ShaderNode*> newnodes;
foreach(ShaderNode *node, nodes) {
@@ -787,5 +835,47 @@ void ShaderGraph::transform_multi_closure(ShaderNode *node, ShaderOutput *weight
}
}
+void ShaderGraph::dump_graph(const char *filename)
+{
+ FILE *fd = fopen(filename, "w");
+
+ if(fd == NULL) {
+ printf("Error opening file for dumping the graph: %s\n", filename);
+ return;
+ }
+
+ fprintf(fd, "digraph dependencygraph {\n");
+ fprintf(fd, "ranksep=1.5\n");
+ fprintf(fd, "splines=false\n");
+
+ foreach(ShaderNode *node, nodes) {
+ fprintf(fd, "// NODE: %p\n", node);
+ fprintf(fd,
+ "\"%p\" [shape=record,label=\"%s\"]\n",
+ node,
+ node->name.c_str());
+ }
+
+ foreach(ShaderNode *node, nodes) {
+ foreach(ShaderOutput *output, node->outputs) {
+ foreach(ShaderInput *input, output->links) {
+ fprintf(fd,
+ "// CONNECTION: %p->%p (%s:%s)\n",
+ output,
+ input,
+ output->name, input->name);
+ fprintf(fd,
+ "\"%p\":s -> \"%p\":n [label=\"%s:%s\"]\n",
+ output->parent,
+ input->parent,
+ output->name, input->name);
+ }
+ }
+ }
+
+ fprintf(fd, "}\n");
+ fclose(fd);
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index 89a066195d6..7b95703d3aa 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -76,6 +76,7 @@ enum ShaderNodeSpecialType {
SHADER_SPECIAL_TYPE_NONE,
SHADER_SPECIAL_TYPE_PROXY,
SHADER_SPECIAL_TYPE_MIX_CLOSURE,
+ SHADER_SPECIAL_TYPE_MIX_RGB, /* Only Mix subtype */
SHADER_SPECIAL_TYPE_AUTOCONVERT,
SHADER_SPECIAL_TYPE_GEOMETRY,
SHADER_SPECIAL_TYPE_SCRIPT
@@ -249,6 +250,8 @@ public:
void remove_unneeded_nodes();
void finalize(bool do_bump = false, bool do_osl = false);
+ void dump_graph(const char *filename);
+
protected:
typedef pair<ShaderNode* const, ShaderNode*> NodePair;
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 076cc3d8b63..eb2c3333c44 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -176,6 +176,10 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani
img->frame = frame;
img->need_load = true;
}
+ if(img->use_alpha != use_alpha) {
+ img->use_alpha = use_alpha;
+ img->need_load = true;
+ }
img->users++;
return slot;
}
@@ -219,6 +223,10 @@ int ImageManager::add_image(const string& filename, void *builtin_data, bool ani
img->frame = frame;
img->need_load = true;
}
+ if(img->use_alpha != use_alpha) {
+ img->use_alpha = use_alpha;
+ img->need_load = true;
+ }
img->users++;
return slot+tex_image_byte_start;
}
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 8299cd02fef..42103396b53 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -378,12 +378,12 @@ void Mesh::add_vertex_normals()
}
}
-void Mesh::pack_normals(Scene *scene, float *tri_shader, float4 *vnormal)
+void Mesh::pack_normals(Scene *scene, uint *tri_shader, float4 *vnormal)
{
Attribute *attr_vN = attributes.find(ATTR_STD_VERTEX_NORMAL);
float3 *vN = attr_vN->data_float3();
- int shader_id = 0;
+ uint shader_id = 0;
uint last_shader = -1;
bool last_smooth = false;
@@ -401,7 +401,7 @@ void Mesh::pack_normals(Scene *scene, float *tri_shader, float4 *vnormal)
shader_id = scene->shader_manager->get_shader_id(last_shader, this, last_smooth);
}
- tri_shader[i] = __int_as_float(shader_id);
+ tri_shader[i] = shader_id;
}
size_t verts_size = verts.size();
@@ -936,7 +936,7 @@ void MeshManager::device_update_mesh(Device *device, DeviceScene *dscene, Scene
/* normals */
progress.set_status("Updating Mesh", "Computing normals");
- float *tri_shader = dscene->tri_shader.resize(tri_size);
+ uint *tri_shader = dscene->tri_shader.resize(tri_size);
float4 *vnormal = dscene->tri_vnormal.resize(vert_size);
float4 *tri_verts = dscene->tri_verts.resize(vert_size);
float4 *tri_vindex = dscene->tri_vindex.resize(tri_size);
@@ -1032,11 +1032,16 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
if(!need_update)
return;
- /* update normals */
+ /* update normals and flags */
foreach(Mesh *mesh, scene->meshes) {
- foreach(uint shader, mesh->used_shaders)
+ mesh->has_volume = false;
+ foreach(uint shader, mesh->used_shaders) {
if(scene->shaders[shader]->need_update_attributes)
mesh->need_update = true;
+ if(scene->shaders[shader]->has_volume) {
+ mesh->has_volume = true;
+ }
+ }
if(mesh->need_update) {
mesh->add_face_normals();
@@ -1104,6 +1109,8 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
bool motion_blur = false;
#endif
+ /* update obejcts */
+ vector<Object *> volume_objects;
foreach(Object *object, scene->objects)
object->compute_bounds(motion_blur);
diff --git a/intern/cycles/render/mesh.h b/intern/cycles/render/mesh.h
index d45905611fa..7e34b761faf 100644
--- a/intern/cycles/render/mesh.h
+++ b/intern/cycles/render/mesh.h
@@ -79,6 +79,8 @@ public:
vector<uint> shader;
vector<bool> smooth;
+ bool has_volume; /* Set in the device_update(). */
+
vector<float4> curve_keys; /* co + radius */
vector<Curve> curves;
@@ -123,7 +125,7 @@ public:
void add_face_normals();
void add_vertex_normals();
- void pack_normals(Scene *scene, float *shader, float4 *vnormal);
+ void pack_normals(Scene *scene, uint *shader, float4 *vnormal);
void pack_verts(float4 *tri_verts, float4 *tri_vindex, size_t vert_offset);
void pack_curves(Scene *scene, float4 *curve_key_co, float4 *curve_data, size_t curvekey_offset);
void compute_bvh(SceneParams *params, Progress *progress, int n, int total);
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 1f148d34ea6..46ddab235d9 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -75,8 +75,14 @@ void Object::compute_bounds(bool motion_blur)
bounds.grow(mbounds.transformed(&ttfm));
}
}
- else
- bounds = mbounds.transformed(&tfm);
+ else {
+ if(mesh->transform_applied) {
+ bounds = mbounds;
+ }
+ else {
+ bounds = mbounds.transformed(&tfm);
+ }
+ }
}
void Object::apply_transform(bool apply_to_motion)
@@ -372,8 +378,6 @@ void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *sc
device_free(device, dscene);
- need_update = false;
-
if(scene->objects.size() == 0)
return;
@@ -392,6 +396,46 @@ void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *sc
progress.set_status("Updating Objects", "Applying Static Transformations");
apply_static_transforms(dscene, scene, object_flag, progress);
}
+}
+
+void ObjectManager::device_update_flags(Device *device, DeviceScene *dscene,
+ Scene *scene, Progress& progress)
+{
+ if(!need_update)
+ return;
+
+ need_update = false;
+
+ if(scene->objects.size() == 0)
+ return;
+
+ /* object info flag */
+ uint *object_flag = dscene->object_flag.get_data();
+
+ vector<Object *> volume_objects;
+ foreach(Object *object, scene->objects) {
+ if(object->mesh->has_volume) {
+ volume_objects.push_back(object);
+ }
+ }
+
+ int object_index = 0;
+ foreach(Object *object, scene->objects) {
+ if(object->mesh->has_volume) {
+ object_flag[object_index] |= SD_OBJECT_HAS_VOLUME;
+ }
+
+ foreach(Object *volume_object, volume_objects) {
+ if(object == volume_object) {
+ continue;
+ }
+ if(object->bounds.intersects(volume_object->bounds)) {
+ object_flag[object_index] |= SD_OBJECT_INTERSECTS_VOLUME;
+ break;
+ }
+ }
+ ++object_index;
+ }
/* allocate object flag */
device->tex_alloc("__object_flag", dscene->object_flag);
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 677526b715f..2c69b83a2e9 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -76,6 +76,7 @@ public:
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, uint *object_flag, Progress& progress);
+ void device_update_flags(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
void tag_update(Scene *scene);
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 796007b64a8..6c3f98bc9b0 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -165,13 +165,18 @@ void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel()) return;
- progress.set_status("Updating Camera");
- camera->device_update(device, &dscene, this);
+ progress.set_status("Updating Objects");
+ object_manager->device_update(device, &dscene, this, progress);
if(progress.get_cancel()) return;
- progress.set_status("Updating Objects");
- object_manager->device_update(device, &dscene, this, progress);
+ progress.set_status("Updating Meshes");
+ mesh_manager->device_update(device, &dscene, this, progress);
+
+ if(progress.get_cancel()) return;
+
+ progress.set_status("Updating Objects Flags");
+ object_manager->device_update_flags(device, &dscene, this, progress);
if(progress.get_cancel()) return;
@@ -185,8 +190,9 @@ void Scene::device_update(Device *device_, Progress& progress)
if(progress.get_cancel()) return;
- progress.set_status("Updating Meshes");
- mesh_manager->device_update(device, &dscene, this, progress);
+ /* TODO(sergey): Make sure camera is not needed above. */
+ progress.set_status("Updating Camera");
+ camera->device_update(device, &dscene, this);
if(progress.get_cancel()) return;
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index e5c7444c92d..5d205225d97 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -69,7 +69,7 @@ public:
device_vector<uint> prim_object;
/* mesh */
- device_vector<float> tri_shader;
+ device_vector<uint> tri_shader;
device_vector<float4> tri_vnormal;
device_vector<float4> tri_vindex;
device_vector<float4> tri_verts;
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 0ed6d2ddf01..368496fd188 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -17,6 +17,10 @@
#ifndef __SHADER_H__
#define __SHADER_H__
+#ifdef WITH_OSL
+# include <OSL/oslexec.h>
+#endif
+
#include "attribute.h"
#include "kernel_types.h"
@@ -25,10 +29,6 @@
#include "util_string.h"
#include "util_types.h"
-#ifdef WITH_OSL
-#include <OSL/oslexec.h>
-#endif
-
CCL_NAMESPACE_BEGIN
class Device;
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index d6094a4fa0a..e37d8e5f8a1 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -200,8 +200,8 @@ list<Tile>::iterator TileManager::next_background_tile(int device, TileOrder til
switch (tile_order) {
case TILE_CENTER:
- distx = centx - (cur_tile.x + cur_tile.w);
- disty = centy - (cur_tile.y + cur_tile.h);
+ distx = centx - (cur_tile.x + (cur_tile.w / 2));
+ disty = centy - (cur_tile.y + (cur_tile.h / 2));
distx = (int64_t)sqrt((double)(distx * distx + disty * disty));
break;
case TILE_RIGHT_TO_LEFT:
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index 7b3301e8abe..842d5efac79 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -11,6 +11,7 @@ set(INC_SYS
set(SRC
util_cache.cpp
util_dynlib.cpp
+ util_logging.cpp
util_md5.cpp
util_path.cpp
util_string.cpp
@@ -40,6 +41,7 @@ set(SRC_HEADERS
util_hash.h
util_image.h
util_list.h
+ util_logging.h
util_map.h
util_math.h
util_md5.h
diff --git a/intern/cycles/util/util_boundbox.h b/intern/cycles/util/util_boundbox.h
index 369082af60a..a71e0399619 100644
--- a/intern/cycles/util/util_boundbox.h
+++ b/intern/cycles/util/util_boundbox.h
@@ -167,6 +167,15 @@ public:
return result;
}
+
+ __forceinline bool intersects(const BoundBox& other)
+ {
+ float3 center_diff = center() - other.center(),
+ total_size = (size() + other.size()) * 0.5f;
+ return fabsf(center_diff.x) <= total_size.x &&
+ fabsf(center_diff.y) <= total_size.y &&
+ fabsf(center_diff.z) <= total_size.z;
+ }
};
__forceinline BoundBox merge(const BoundBox& bbox, const float3& pt)
diff --git a/intern/cycles/util/util_color.h b/intern/cycles/util/util_color.h
index 48e9e2d025f..53b3d72de67 100644
--- a/intern/cycles/util/util_color.h
+++ b/intern/cycles/util/util_color.h
@@ -170,7 +170,7 @@ ccl_device float3 color_srgb_to_scene_linear(float3 c)
#ifdef __KERNEL_SSE2__
/*
* Calculate initial guess for arg^exp based on float representation
- * This method gives a constant bias, which can be easily compensated by multiplicating with bias_coeff.
+ * This method gives a constant bias, which can be easily compensated by multiplication with bias_coeff.
* Gives better results for exponents near 1 (e. g. 4/5).
* exp = exponent, encoded as uint32_t
* e2coeff = 2^(127/exponent - 127) * bias_coeff^(1/exponent), encoded as uint32_t
diff --git a/intern/cycles/util/util_logging.cpp b/intern/cycles/util/util_logging.cpp
new file mode 100644
index 00000000000..0722f16cf45
--- /dev/null
+++ b/intern/cycles/util/util_logging.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2011-2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#include <util_logging.h>
+
+#include "util_math.h"
+
+CCL_NAMESPACE_BEGIN
+
+std::ostream& operator <<(std::ostream &os,
+ const float3 &value)
+{
+ os << "(" << value.x
+ << ", " << value.y
+ << ", " << value.z
+ << ")";
+ return os;
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_logging.h b/intern/cycles/util/util_logging.h
new file mode 100644
index 00000000000..991789e7460
--- /dev/null
+++ b/intern/cycles/util/util_logging.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2011-2014 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+#ifndef __UTIL_LOGGING_H__
+#define __UTIL_LOGGING_H__
+
+#if defined(WITH_CYCLES_LOGGING) && !defined(__KERNEL_GPU__)
+# include <glog/logging.h>
+#else
+# include <iostream>
+#endif
+
+CCL_NAMESPACE_BEGIN
+
+#if !defined(WITH_CYCLES_LOGGING) || defined(__KERNEL_GPU__)
+class StubStream : public std::ostream {
+ public:
+ StubStream() : std::ostream(NULL) { }
+};
+
+class LogMessageVoidify {
+public:
+ LogMessageVoidify() { }
+ void operator&(::std::ostream&) { }
+};
+
+# define LOG_SUPPRESS() (true) ? (void) 0 : LogMessageVoidify() & StubStream()
+# define LOG(severity) LOG_SUPPRESS()
+# define VLOG(severity) LOG_SUPPRESS()
+
+#endif
+
+class float3;
+
+std::ostream& operator <<(std::ostream &os,
+ const float3 &value);
+
+CCL_NAMESPACE_END
+
+#endif /* __UTIL_LOGGING_H__ */
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index d7d80e2cffd..2a199e591bf 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -33,14 +33,17 @@
#ifndef __KERNEL_GPU__
-#define ccl_device static inline
+# ifdef NDEBUG
+# define ccl_device static inline
+# else
+# define ccl_device static
+# endif
#define ccl_device_noinline static
#define ccl_global
#define ccl_constant
#define __KERNEL_WITH_SSE_ALIGN__
#if defined(_WIN32) && !defined(FREE_WINDOWS)
-
#define ccl_device_inline static __forceinline
#define ccl_align(...) __declspec(align(__VA_ARGS__))
#ifdef __KERNEL_64_BIT__
@@ -50,7 +53,11 @@
#define ccl_try_align(...) /* not support for function arguments (error C2719) */
#endif
#define ccl_may_alias
-#define ccl_always_inline __forceinline
+# ifdef NDEBUG
+# define ccl_always_inline __forceinline
+# else
+# define ccl_always_inline
+# endif
#define ccl_maybe_unused
#else
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index a2e26574530..236002e9744 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -530,7 +530,8 @@ GHOST_IWindow* GHOST_SystemCocoa::createWindow(
//Ensures window top left is inside this available rect
left = left > contentRect.origin.x ? left : contentRect.origin.x;
- bottom = bottom > contentRect.origin.y ? bottom : contentRect.origin.y;
+ // Add contentRect.origin.y to respect docksize
+ bottom = bottom > contentRect.origin.y ? bottom + contentRect.origin.y : contentRect.origin.y;
window = new GHOST_WindowCocoa (this, title, left, bottom, width, height, state, type, stereoVisual, numOfAASamples);
@@ -703,7 +704,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
// For some reason NSApp is swallowing the key up events when modifier
// key is pressed, even if there seems to be no apparent reason to do
// so, as a workaround we always handle these up events.
- if ([event type] == NSKeyUp && (([event modifierFlags] & NSCommandKeyMask) || ([event modifierFlags] & NSAlternateKeyMask)))
+ if ([event type] == NSKeyUp && ([event modifierFlags] & (NSCommandKeyMask | NSAlternateKeyMask)))
handleKeyEvent(event);
[NSApp sendEvent:event];
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c
index 40f406d0ae2..be0a8aadf84 100644
--- a/intern/guardedalloc/intern/mallocn.c
+++ b/intern/guardedalloc/intern/mallocn.c
@@ -72,6 +72,7 @@ void *aligned_malloc(size_t size, size_t alignment)
* they work natively with SSE types with no further work.
*/
assert(alignment == 16);
+ (void)alignment;
return malloc(size);
#elif defined(__FreeBSD__) || defined(__NetBSD__)
void *result;
diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h
index 523d1786b97..7da74f7cc4c 100644
--- a/intern/guardedalloc/intern/mallocn_intern.h
+++ b/intern/guardedalloc/intern/mallocn_intern.h
@@ -103,6 +103,13 @@
# include <stdlib.h>
#endif
+/* visual studio 2012 does not define inline for C */
+#ifdef _MSC_VER
+# define MEM_INLINE static __inline
+#else
+# define MEM_INLINE static inline
+#endif
+
#define IS_POW2(a) (((a) & ((a) - 1)) == 0)
/* Extra padding which needs to be applied on MemHead to make it aligned. */
diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
index ffb23702601..c0f6aeeaa9d 100644
--- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c
+++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c
@@ -70,6 +70,23 @@ enum {
#define MEMHEAD_IS_MMAP(memhead) ((memhead)->len & (size_t) MEMHEAD_MMAP_FLAG)
#define MEMHEAD_IS_ALIGNED(memhead) ((memhead)->len & (size_t) MEMHEAD_ALIGN_FLAG)
+/* Uncomment this to have proper peak counter. */
+//#define USE_ATOMIC_MAX
+
+MEM_INLINE void update_maximum(size_t *maximum_value, size_t value)
+{
+#ifdef USE_ATOMIC_MAX
+ size_t prev_value = *maximum_value;
+ while (prev_value < value) {
+ if (atomic_cas_z(maximum_value, prev_value, value) != prev_value) {
+ break;
+ }
+ }
+#else
+ *maximum_value = value > *maximum_value ? value : *maximum_value;
+#endif
+}
+
#ifdef __GNUC__
__attribute__ ((format(printf, 1, 2)))
#endif
@@ -264,9 +281,7 @@ void *MEM_lockfree_callocN(size_t len, const char *str)
memh->len = len;
atomic_add_u(&totblock, 1);
atomic_add_z(&mem_in_use, len);
-
- /* TODO(sergey): Not strictly speaking thread-safe. */
- peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
+ update_maximum(&peak_mem, mem_in_use);
return PTR_FROM_MEMHEAD(memh);
}
@@ -291,9 +306,7 @@ void *MEM_lockfree_mallocN(size_t len, const char *str)
memh->len = len;
atomic_add_u(&totblock, 1);
atomic_add_z(&mem_in_use, len);
-
- /* TODO(sergey): Not strictly speaking thread-safe. */
- peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
+ update_maximum(&peak_mem, mem_in_use);
return PTR_FROM_MEMHEAD(memh);
}
@@ -342,9 +355,7 @@ void *MEM_lockfree_mallocN_aligned(size_t len, size_t alignment, const char *str
memh->alignment = (short) alignment;
atomic_add_u(&totblock, 1);
atomic_add_z(&mem_in_use, len);
-
- /* TODO(sergey): Not strictly speaking thread-safe. */
- peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
+ update_maximum(&peak_mem, mem_in_use);
return PTR_FROM_MEMHEAD(memh);
}
@@ -381,9 +392,8 @@ void *MEM_lockfree_mapallocN(size_t len, const char *str)
atomic_add_z(&mem_in_use, len);
atomic_add_z(&mmap_in_use, len);
- /* TODO(sergey): Not strictly speaking thread-safe. */
- peak_mem = mem_in_use > peak_mem ? mem_in_use : peak_mem;
- peak_mem = mmap_in_use > peak_mem ? mmap_in_use : peak_mem;
+ update_maximum(&peak_mem, mem_in_use);
+ update_maximum(&peak_mem, mmap_in_use);
return PTR_FROM_MEMHEAD(memh);
}
diff --git a/intern/opennl/extern/ONL_opennl.h b/intern/opennl/extern/ONL_opennl.h
index 721da202c13..c89a4aaf1f4 100644
--- a/intern/opennl/extern/ONL_opennl.h
+++ b/intern/opennl/extern/ONL_opennl.h
@@ -100,11 +100,11 @@ NLContext nlGetCurrent(void);
/* State get/set */
-void nlSolverParameterf(NLenum pname, NLfloat param);
+void nlSolverParameterf(NLenum pname, NLdouble param);
void nlSolverParameteri(NLenum pname, NLint param);
void nlGetBooleanv(NLenum pname, NLboolean* params);
-void nlGetFloatv(NLenum pname, NLfloat* params);
+void nlGetFloatv(NLenum pname, NLdouble* params);
void nlGetIntergerv(NLenum pname, NLint* params);
void nlEnable(NLenum pname);
@@ -113,8 +113,8 @@ NLboolean nlIsEnabled(NLenum pname);
/* Variables */
-void nlSetVariable(NLuint rhsindex, NLuint index, NLfloat value);
-NLfloat nlGetVariable(NLuint rhsindex, NLuint index);
+void nlSetVariable(NLuint rhsindex, NLuint index, NLdouble value);
+NLdouble nlGetVariable(NLuint rhsindex, NLuint index);
void nlLockVariable(NLuint index);
void nlUnlockVariable(NLuint index);
NLboolean nlVariableIsLocked(NLuint index);
@@ -126,13 +126,9 @@ void nlEnd(NLenum primitive);
/* Setting elements in matrix/vector */
-void nlMatrixAdd(NLuint row, NLuint col, NLfloat value);
-void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLfloat value);
-void nlRightHandSideSet(NLuint rhsindex, NLuint index, NLfloat value);
-
-/* Multiply */
-
-void nlMatrixMultiply(NLfloat *x, NLfloat *y);
+void nlMatrixAdd(NLuint row, NLuint col, NLdouble value);
+void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLdouble value);
+void nlRightHandSideSet(NLuint rhsindex, NLuint index, NLdouble value);
/* Solve */
diff --git a/intern/opennl/intern/opennl.c b/intern/opennl/intern/opennl.c
index f9c63e9ecf6..8cf4bf1327b 100644
--- a/intern/opennl/intern/opennl.c
+++ b/intern/opennl/intern/opennl.c
@@ -69,7 +69,7 @@ static void __nl_assertion_failed(char* cond, char* file, int line) {
}
static void __nl_range_assertion_failed(
- float x, float min_val, float max_val, char* file, int line
+ double x, double min_val, double max_val, char* file, int line
) {
fprintf(
stderr,
@@ -151,7 +151,7 @@ static void __nl_should_not_have_reached(char* file, int line) {
typedef struct {
NLuint index;
- NLfloat value;
+ NLdouble value;
} __NLCoeff;
typedef struct {
@@ -183,7 +183,7 @@ static void __nlRowColumnGrow(__NLRowColumn* c) {
}
}
-static void __nlRowColumnAdd(__NLRowColumn* c, NLint index, NLfloat value) {
+static void __nlRowColumnAdd(__NLRowColumn* c, NLint index, NLdouble value) {
NLuint i;
for(i=0; i<c->size; i++) {
if(c->coeff[i].index == (NLuint)index) {
@@ -200,7 +200,7 @@ static void __nlRowColumnAdd(__NLRowColumn* c, NLint index, NLfloat value) {
}
/* Does not check whether the index already exists */
-static void __nlRowColumnAppend(__NLRowColumn* c, NLint index, NLfloat value) {
+static void __nlRowColumnAppend(__NLRowColumn* c, NLint index, NLdouble value) {
if(c->size == c->capacity) {
__nlRowColumnGrow(c);
}
@@ -229,7 +229,7 @@ typedef struct {
NLenum storage;
__NLRowColumn* row;
__NLRowColumn* column;
- NLfloat* diag;
+ NLdouble* diag;
} __NLSparseMatrix;
@@ -259,7 +259,7 @@ static void __nlSparseMatrixConstruct(
}
M->diag_size = MIN(m,n);
- M->diag = __NL_NEW_ARRAY(NLfloat, M->diag_size);
+ M->diag = __NL_NEW_ARRAY(NLdouble, M->diag_size);
}
static void __nlSparseMatrixDestroy(__NLSparseMatrix* M) {
@@ -283,7 +283,7 @@ static void __nlSparseMatrixDestroy(__NLSparseMatrix* M) {
}
static void __nlSparseMatrixAdd(
- __NLSparseMatrix* M, NLuint i, NLuint j, NLfloat value
+ __NLSparseMatrix* M, NLuint i, NLuint j, NLdouble value
) {
__nl_parano_range_assert(i, 0, M->m - 1);
__nl_parano_range_assert(j, 0, M->n - 1);
@@ -313,7 +313,7 @@ static void __nlSparseMatrixClear( __NLSparseMatrix* M) {
__nlRowColumnClear(&(M->column[i]));
}
}
- __NL_CLEAR_ARRAY(NLfloat, M->diag, M->diag_size);
+ __NL_CLEAR_ARRAY(NLdouble, M->diag, M->diag_size);
}
/* Returns the number of non-zero coefficients */
@@ -338,7 +338,7 @@ static NLuint __nlSparseMatrixNNZ( __NLSparseMatrix* M) {
/* SparseMatrix x Vector routines, internal helper routines */
static void __nlSparseMatrix_mult_rows_symmetric(
- __NLSparseMatrix* A, NLfloat* x, NLfloat* y
+ __NLSparseMatrix* A, NLdouble* x, NLdouble* y
) {
NLuint m = A->m;
NLuint i,ij;
@@ -358,7 +358,7 @@ static void __nlSparseMatrix_mult_rows_symmetric(
}
static void __nlSparseMatrix_mult_rows(
- __NLSparseMatrix* A, NLfloat* x, NLfloat* y
+ __NLSparseMatrix* A, NLdouble* x, NLdouble* y
) {
NLuint m = A->m;
NLuint i,ij;
@@ -375,7 +375,7 @@ static void __nlSparseMatrix_mult_rows(
}
static void __nlSparseMatrix_mult_cols_symmetric(
- __NLSparseMatrix* A, NLfloat* x, NLfloat* y
+ __NLSparseMatrix* A, NLdouble* x, NLdouble* y
) {
NLuint n = A->n;
NLuint j,ii;
@@ -395,13 +395,13 @@ static void __nlSparseMatrix_mult_cols_symmetric(
}
static void __nlSparseMatrix_mult_cols(
- __NLSparseMatrix* A, NLfloat* x, NLfloat* y
+ __NLSparseMatrix* A, NLdouble* x, NLdouble* y
) {
NLuint n = A->n;
NLuint j,ii;
__NLRowColumn* Cj = NULL;
__NLCoeff* c = NULL;
- __NL_CLEAR_ARRAY(NLfloat, y, A->m);
+ __NL_CLEAR_ARRAY(NLdouble, y, A->m);
for(j=0; j<n; j++) {
Cj = &(A->column[j]);
for(ii=0; ii<Cj->size; ii++) {
@@ -414,7 +414,7 @@ static void __nlSparseMatrix_mult_cols(
/************************************************************************************/
/* SparseMatrix x Vector routines, main driver routine */
-static void __nlSparseMatrixMult(__NLSparseMatrix* A, NLfloat* x, NLfloat* y) {
+static void __nlSparseMatrixMult(__NLSparseMatrix* A, NLdouble* x, NLdouble* y) {
if(A->storage & __NL_ROWS) {
if(A->storage & __NL_SYMMETRIC) {
__nlSparseMatrix_mult_rows_symmetric(A, x, y);
@@ -440,7 +440,7 @@ static void __nlSparseMatrix_square(
NLuint i, j0, j1;
__NLRowColumn *Ri = NULL;
__NLCoeff *c0 = NULL, *c1 = NULL;
- float value;
+ double value;
__nlSparseMatrixConstruct(AtA, n, n, A->storage);
@@ -460,7 +460,7 @@ static void __nlSparseMatrix_square(
}
static void __nlSparseMatrix_transpose_mult_rows(
- __NLSparseMatrix* A, NLfloat* x, NLfloat* y
+ __NLSparseMatrix* A, NLdouble* x, NLdouble* y
) {
NLuint m = A->m;
NLuint n = A->n;
@@ -468,7 +468,7 @@ static void __nlSparseMatrix_transpose_mult_rows(
__NLRowColumn* Ri = NULL;
__NLCoeff* c = NULL;
- __NL_CLEAR_ARRAY(NLfloat, y, n);
+ __NL_CLEAR_ARRAY(NLdouble, y, n);
for(i=0; i<m; i++) {
Ri = &(A->row[i]);
@@ -482,10 +482,10 @@ static void __nlSparseMatrix_transpose_mult_rows(
/************************************************************************************/
/* NLContext data structure */
-typedef void(*__NLMatrixFunc)(float* x, float* y);
+typedef void(*__NLMatrixFunc)(double* x, double* y);
typedef struct {
- NLfloat value[4];
+ NLdouble value[4];
NLboolean locked;
NLuint index;
__NLRowColumn *a;
@@ -503,11 +503,11 @@ typedef struct {
NLuint n;
NLuint m;
__NLVariable* variable;
- NLfloat* b;
- NLfloat* Mtb;
+ NLdouble* b;
+ NLdouble* Mtb;
__NLSparseMatrix M;
__NLSparseMatrix MtM;
- NLfloat* x;
+ NLdouble* x;
NLuint nb_variables;
NLuint nb_rows;
NLboolean least_squares;
@@ -520,7 +520,7 @@ typedef struct {
NLboolean alloc_x;
NLboolean alloc_b;
NLboolean alloc_Mtb;
- NLfloat error;
+ NLdouble error;
__NLMatrixFunc matrix_vector_prod;
struct __NLSuperLUContext {
@@ -533,7 +533,7 @@ typedef struct {
static __NLContext* __nlCurrentContext = NULL;
-static void __nlMatrixVectorProd_default(NLfloat* x, NLfloat* y) {
+static void __nlMatrixVectorProd_default(NLdouble* x, NLdouble* y) {
__nlSparseMatrixMult(&(__nlCurrentContext->M), x, y);
}
@@ -611,7 +611,7 @@ static void __nlTransition(NLenum from_state, NLenum to_state) {
/************************************************************************************/
/* Get/Set parameters */
-void nlSolverParameterf(NLenum pname, NLfloat param) {
+void nlSolverParameterf(NLenum pname, NLdouble param) {
__nlCheckState(__NL_STATE_INITIAL);
switch(pname) {
case NL_NB_VARIABLES: {
@@ -677,22 +677,22 @@ void nlGetBooleanv(NLenum pname, NLboolean* params) {
}
}
-void nlGetFloatv(NLenum pname, NLfloat* params) {
+void nlGetFloatv(NLenum pname, NLdouble* params) {
switch(pname) {
case NL_NB_VARIABLES: {
- *params = (NLfloat)(__nlCurrentContext->nb_variables);
+ *params = (NLdouble)(__nlCurrentContext->nb_variables);
} break;
case NL_NB_ROWS: {
- *params = (NLfloat)(__nlCurrentContext->nb_rows);
+ *params = (NLdouble)(__nlCurrentContext->nb_rows);
} break;
case NL_LEAST_SQUARES: {
- *params = (NLfloat)(__nlCurrentContext->least_squares);
+ *params = (NLdouble)(__nlCurrentContext->least_squares);
} break;
case NL_SYMMETRIC: {
- *params = (NLfloat)(__nlCurrentContext->symmetric);
+ *params = (NLdouble)(__nlCurrentContext->symmetric);
} break;
case NL_ERROR: {
- *params = (NLfloat)(__nlCurrentContext->error);
+ *params = (NLdouble)(__nlCurrentContext->error);
} break;
default: {
__nl_assert_not_reached;
@@ -751,13 +751,13 @@ NLboolean nlIsEnabled(NLenum pname) {
/************************************************************************************/
/* Get/Set Lock/Unlock variables */
-void nlSetVariable(NLuint rhsindex, NLuint index, NLfloat value) {
+void nlSetVariable(NLuint rhsindex, NLuint index, NLdouble value) {
__nlCheckState(__NL_STATE_SYSTEM);
__nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
__nlCurrentContext->variable[index].value[rhsindex] = value;
}
-NLfloat nlGetVariable(NLuint rhsindex, NLuint index) {
+NLdouble nlGetVariable(NLuint rhsindex, NLuint index) {
__nl_assert(__nlCurrentContext->state != __NL_STATE_INITIAL);
__nl_parano_range_assert(index, 0, __nlCurrentContext->nb_variables - 1);
return __nlCurrentContext->variable[index].value[rhsindex];
@@ -870,15 +870,15 @@ static void __nlBeginMatrix() {
__nlSparseMatrixConstruct(&context->M, m, n, storage);
context->alloc_M = NL_TRUE;
- context->b = __NL_NEW_ARRAY(NLfloat, m*context->nb_rhs);
+ context->b = __NL_NEW_ARRAY(NLdouble, m*context->nb_rhs);
context->alloc_b = NL_TRUE;
- context->x = __NL_NEW_ARRAY(NLfloat, n*context->nb_rhs);
+ context->x = __NL_NEW_ARRAY(NLdouble, n*context->nb_rhs);
context->alloc_x = NL_TRUE;
}
else {
/* need to recompute b only, A is not constructed anymore */
- __NL_CLEAR_ARRAY(NLfloat, context->b, context->m*context->nb_rhs);
+ __NL_CLEAR_ARRAY(NLdouble, context->b, context->m*context->nb_rhs);
}
__nlVariablesToVector();
@@ -888,7 +888,7 @@ static void __nlEndMatrixRHS(NLuint rhs) {
__NLContext *context = __nlCurrentContext;
__NLVariable *variable;
__NLRowColumn *a;
- NLfloat *b, *Mtb;
+ NLdouble *b, *Mtb;
NLuint i, j;
b = context->b + context->m*rhs;
@@ -922,7 +922,7 @@ static void __nlEndMatrix() {
context->alloc_MtM = NL_TRUE;
context->Mtb =
- __NL_NEW_ARRAY(NLfloat, context->n*context->nb_rhs);
+ __NL_NEW_ARRAY(NLdouble, context->n*context->nb_rhs);
context->alloc_Mtb = NL_TRUE;
}
}
@@ -931,7 +931,7 @@ static void __nlEndMatrix() {
__nlEndMatrixRHS(i);
}
-void nlMatrixAdd(NLuint row, NLuint col, NLfloat value)
+void nlMatrixAdd(NLuint row, NLuint col, NLdouble value)
{
__NLContext *context = __nlCurrentContext;
@@ -960,10 +960,10 @@ void nlMatrixAdd(NLuint row, NLuint col, NLfloat value)
}
}
-void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLfloat value)
+void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLdouble value)
{
__NLContext *context = __nlCurrentContext;
- NLfloat* b = context->b;
+ NLdouble* b = context->b;
__nlCheckState(__NL_STATE_MATRIX);
@@ -981,10 +981,10 @@ void nlRightHandSideAdd(NLuint rhsindex, NLuint index, NLfloat value)
}
}
-void nlRightHandSideSet(NLuint rhsindex, NLuint index, NLfloat value)
+void nlRightHandSideSet(NLuint rhsindex, NLuint index, NLdouble value)
{
__NLContext *context = __nlCurrentContext;
- NLfloat* b = context->b;
+ NLdouble* b = context->b;
__nlCheckState(__NL_STATE_MATRIX);
@@ -1047,8 +1047,8 @@ static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation)
/* Compressed Row Storage matrix representation */
NLint *xa = __NL_NEW_ARRAY(NLint, n+1);
- NLfloat *rhs = __NL_NEW_ARRAY(NLfloat, n);
- NLfloat *a = __NL_NEW_ARRAY(NLfloat, nnz);
+ NLdouble *rhs = __NL_NEW_ARRAY(NLdouble, n);
+ NLdouble *a = __NL_NEW_ARRAY(NLdouble, nnz);
NLint *asub = __NL_NEW_ARRAY(NLint, nnz);
NLint *etree = __NL_NEW_ARRAY(NLint, n);
@@ -1083,7 +1083,7 @@ static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation)
sCreate_CompCol_Matrix(
&At, n, n, nnz, a, asub, xa,
SLU_NC, /* Colum wise, no supernode */
- SLU_S, /* floats */
+ SLU_S, /* doubles */
SLU_GE /* general storage */
);
@@ -1136,8 +1136,8 @@ static NLboolean __nlFactorize_SUPERLU(__NLContext *context, NLint *permutation)
static NLboolean __nlInvert_SUPERLU(__NLContext *context) {
/* OpenNL Context */
- NLfloat* b = (context->least_squares)? context->Mtb: context->b;
- NLfloat* x = context->x;
+ NLdouble* b = (context->least_squares)? context->Mtb: context->b;
+ NLdouble* x = context->x;
NLuint n = context->n, j;
/* SuperLU variables */
@@ -1149,7 +1149,7 @@ static NLboolean __nlInvert_SUPERLU(__NLContext *context) {
sCreate_Dense_Matrix(
&B, n, 1, b, n,
SLU_DN, /* Fortran-type column-wise storage */
- SLU_S, /* floats */
+ SLU_S, /* doubles */
SLU_GE /* general */
);
@@ -1184,12 +1184,12 @@ void nlPrintMatrix(void) {
__NLContext *context = __nlCurrentContext;
__NLSparseMatrix* M = &(context->M);
__NLSparseMatrix* MtM = &(context->MtM);
- float *b = context->b;
+ double *b = context->b;
NLuint i, jj, k;
NLuint m = context->m;
NLuint n = context->n;
__NLRowColumn* Ri = NULL;
- float *value = malloc(sizeof(*value)*(n+m));
+ double *value = malloc(sizeof(*value)*(n+m));
printf("A:\n");
for(i=0; i<m; i++) {
diff --git a/intern/opennl/superlu/scolumn_bmod.c b/intern/opennl/superlu/scolumn_bmod.c
index 3d4f5968778..9854115b894 100644
--- a/intern/opennl/superlu/scolumn_bmod.c
+++ b/intern/opennl/superlu/scolumn_bmod.c
@@ -29,9 +29,9 @@
/*
* Function prototypes
*/
-void susolve(int, int, float*, float*);
-void slsolve(int, int, float*, float*);
-void smatvec(int, int, int, float*, float*, float*);
+void susolve(int, int, double*, double*);
+void slsolve(int, int, double*, double*);
+void smatvec(int, int, int, double*, double*, double*);
@@ -42,8 +42,8 @@ int
scolumn_bmod (
const int jcol, /* in */
const int nseg, /* in */
- float *dense, /* in */
- float *tempv, /* working array */
+ double *dense, /* in */
+ double *tempv, /* working array */
int *segrep, /* in */
int *repfnz, /* in */
int fpanelc, /* in -- first column in the current panel */
@@ -67,7 +67,7 @@ scolumn_bmod (
#ifdef USE_VENDOR_BLAS
int incx = 1, incy = 1;
- float alpha, beta;
+ double alpha, beta;
#endif
/* krep = representative of current k-th supernode
@@ -78,7 +78,7 @@ scolumn_bmod (
* kfnz = first nonz in the k-th supernodal segment
* no_zeros = no of leading zeros in a supernodal U-segment
*/
- float ukj, ukj1, ukj2;
+ double ukj, ukj1, ukj2;
int luptr, luptr1, luptr2;
int fsupc, nsupc, nsupr, segsze;
int nrow; /* No of rows in the matrix of matrix-vector */
@@ -91,14 +91,14 @@ scolumn_bmod (
panel and the first column of the current snode. */
int *xsup, *supno;
int *lsub, *xlsub;
- float *lusup;
+ double *lusup;
int *xlusup;
int nzlumax;
- float *tempv1;
- float zero = 0.0;
+ double *tempv1;
+ double zero = 0.0;
#ifdef USE_VENDOR_BLAS
- float one = 1.0;
- float none = -1.0;
+ double one = 1.0;
+ double none = -1.0;
#endif
int mem_error;
flops_t *ops = stat->ops;
diff --git a/intern/opennl/superlu/scopy_to_ucol.c b/intern/opennl/superlu/scopy_to_ucol.c
index 14904533e3a..4cf7d64a349 100644
--- a/intern/opennl/superlu/scopy_to_ucol.c
+++ b/intern/opennl/superlu/scopy_to_ucol.c
@@ -33,7 +33,7 @@ scopy_to_ucol(
int *segrep, /* in */
int *repfnz, /* in */
int *perm_r, /* in */
- float *dense, /* modified - reset to zero on return */
+ double *dense, /* modified - reset to zero on return */
GlobalLU_t *Glu /* modified */
)
{
@@ -47,11 +47,11 @@ scopy_to_ucol(
int new_next, mem_error;
int *xsup, *supno;
int *lsub, *xlsub;
- float *ucol;
+ double *ucol;
int *usub, *xusub;
int nzumax;
- float zero = 0.0;
+ double zero = 0.0;
xsup = Glu->xsup;
supno = Glu->supno;
diff --git a/intern/opennl/superlu/sgssv.c b/intern/opennl/superlu/sgssv.c
index a653764304a..b2a9848e597 100644
--- a/intern/opennl/superlu/sgssv.c
+++ b/intern/opennl/superlu/sgssv.c
@@ -119,7 +119,7 @@ sgssv(superlu_options_t *options, SuperMatrix *A, int *perm_c, int *perm_r,
* On exit, the solution matrix if info = 0;
*
* stat (output) SuperLUStat_t*
- * Record the statistics on runtime and floating-point operation count.
+ * Record the statistics on runtime and doubleing-point operation count.
* See util.h for the definition of 'SuperLUStat_t'.
*
* info (output) int*
diff --git a/intern/opennl/superlu/sgstrf.c b/intern/opennl/superlu/sgstrf.c
index 335f21165ca..78b1ba21865 100644
--- a/intern/opennl/superlu/sgstrf.c
+++ b/intern/opennl/superlu/sgstrf.c
@@ -56,7 +56,7 @@ sgstrf (superlu_options_t *options, SuperMatrix *A,
* (A->nrow, A->ncol). The type of A can be:
* Stype = SLU_NCP; Dtype = SLU_S; Mtype = SLU_GE.
*
- * drop_tol (input) float (NOT IMPLEMENTED)
+ * drop_tol (input) double (NOT IMPLEMENTED)
* Drop tolerance parameter. At step j of the Gaussian elimination,
* if abs(A_ij)/(max_i abs(A_ij)) < drop_tol, drop entry A_ij.
* 0 <= drop_tol <= 1. The default value of drop_tol is 0.
@@ -119,7 +119,7 @@ sgstrf (superlu_options_t *options, SuperMatrix *A,
* Dtype = SLU_S, Mtype = SLU_TRU.
*
* stat (output) SuperLUStat_t*
- * Record the statistics on runtime and floating-point operation count.
+ * Record the statistics on runtime and doubleing-point operation count.
* See util.h for the definition of 'SuperLUStat_t'.
*
* info (output) int*
@@ -189,14 +189,14 @@ sgstrf (superlu_options_t *options, SuperMatrix *A,
used when options->Fact == SamePattern_SameRowPerm */
int *iperm_c; /* inverse of perm_c */
int *iwork;
- float *swork;
+ double *swork;
int *segrep, *repfnz, *parent, *xplore;
int *panel_lsub; /* dense[]/panel_lsub[] pair forms a w-wide SPA */
int *xprune;
int *marker;
- float *dense, *tempv;
+ double *dense, *tempv;
int *relax_end;
- float *a;
+ double *a;
int *asub;
int *xa_begin, *xa_end;
int *xsup, *supno;
diff --git a/intern/opennl/superlu/sgstrs.c b/intern/opennl/superlu/sgstrs.c
index 0ed59df228e..5387e319d99 100644
--- a/intern/opennl/superlu/sgstrs.c
+++ b/intern/opennl/superlu/sgstrs.c
@@ -28,10 +28,10 @@
/*
* Function prototypes
*/
-void susolve(int, int, float*, float*);
-void slsolve(int, int, float*, float*);
-void smatvec(int, int, int, float*, float*, float*);
-void sprint_soln(int , float *);
+void susolve(int, int, double*, double*);
+void slsolve(int, int, double*, double*);
+void smatvec(int, int, int, double*, double*, double*);
+void sprint_soln(int , double *);
void
sgstrs (trans_t trans, SuperMatrix *L, SuperMatrix *U,
@@ -82,7 +82,7 @@ sgstrs (trans_t trans, SuperMatrix *L, SuperMatrix *U,
* On exit, the solution matrix if info = 0;
*
* stat (output) SuperLUStat_t*
- * Record the statistics on runtime and floating-point operation count.
+ * Record the statistics on runtime and doubleing-point operation count.
* See util.h for the definition of 'SuperLUStat_t'.
*
* info (output) int*
@@ -94,17 +94,17 @@ sgstrs (trans_t trans, SuperMatrix *L, SuperMatrix *U,
_fcd ftcs1, ftcs2, ftcs3, ftcs4;
#endif
#ifdef USE_VENDOR_BLAS
- float alpha = 1.0, beta = 1.0;
- float *work_col;
+ double alpha = 1.0, beta = 1.0;
+ double *work_col;
#endif
DNformat *Bstore;
- float *Bmat;
+ double *Bmat;
SCformat *Lstore;
NCformat *Ustore;
- float *Lval, *Uval;
+ double *Lval, *Uval;
int fsupc, nrow, nsupr, nsupc, luptr, istart, irow;
int i, j, k, iptr, jcol, n, ldb, nrhs;
- float *work, *rhs_work, *soln;
+ double *work, *rhs_work, *soln;
flops_t solve_ops;
void sprint_soln();
@@ -130,9 +130,9 @@ sgstrs (trans_t trans, SuperMatrix *L, SuperMatrix *U,
}
n = L->nrow;
- work = floatCalloc(n * nrhs);
+ work = doubleCalloc(n * nrhs);
if ( !work ) ABORT("Malloc fails for local work[].");
- soln = floatMalloc(n);
+ soln = doubleMalloc(n);
if ( !soln ) ABORT("Malloc fails for local soln[].");
Bmat = Bstore->nzval;
@@ -325,7 +325,7 @@ sgstrs (trans_t trans, SuperMatrix *L, SuperMatrix *U,
* Diagnostic print of the solution vector
*/
void
-sprint_soln(int n, float *soln)
+sprint_soln(int n, double *soln)
{
int i;
diff --git a/intern/opennl/superlu/smemory.c b/intern/opennl/superlu/smemory.c
index 7a2821a4068..a76f60a1758 100644
--- a/intern/opennl/superlu/smemory.c
+++ b/intern/opennl/superlu/smemory.c
@@ -24,8 +24,8 @@
/* Internal prototypes */
void *sexpand (int *, MemType,int, int, GlobalLU_t *);
-int sLUWorkInit (int, int, int, int **, float **, LU_space_t);
-void copy_mem_float (int, void *, void *);
+int sLUWorkInit (int, int, int, int **, double **, LU_space_t);
+void copy_mem_double (int, void *, void *);
void sStackCompress (GlobalLU_t *);
void sSetupSpace (void *, int, LU_space_t *);
void *suser_malloc (int, int);
@@ -59,7 +59,7 @@ static int no_expand;
#define NotDoubleAlign(addr) ( (intptr_t)addr & 7 )
#define DoubleAlign(addr) ( ((intptr_t)addr + 7) & ~7L )
#define TempSpace(m, w) ( (2*w + 4 + NO_MARKER) * m * sizeof(int) + \
- (w + 1) * m * sizeof(float) )
+ (w + 1) * m * sizeof(double) )
#define Reduce(alpha) ((alpha + 1) / 2) /* i.e. (alpha-1)/2 + 1 */
@@ -119,9 +119,9 @@ void suser_free(int bytes, int which_end)
/*
* mem_usage consists of the following fields:
- * - for_lu (float)
+ * - for_lu (double)
* The amount of space used in bytes for the L\U data structures.
- * - total_needed (float)
+ * - total_needed (double)
* The amount of space needed in bytes to perform factorization.
* - expansions (int)
* Number of memory expansions during the LU factorization.
@@ -136,17 +136,17 @@ int sQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage)
Ustore = U->Store;
n = L->ncol;
iword = sizeof(int);
- dword = sizeof(float);
+ dword = sizeof(double);
/* For LU factors */
- mem_usage->for_lu = (float)( (4*n + 3) * iword + Lstore->nzval_colptr[n] *
+ mem_usage->for_lu = (double)( (4*n + 3) * iword + Lstore->nzval_colptr[n] *
dword + Lstore->rowind_colptr[n] * iword );
- mem_usage->for_lu += (float)( (n + 1) * iword +
+ mem_usage->for_lu += (double)( (n + 1) * iword +
Ustore->colptr[n] * (dword + iword) );
/* Working storage to support factorization */
mem_usage->total_needed = mem_usage->for_lu +
- (float)( (2 * panel_size + 4 + NO_MARKER) * n * iword +
+ (double)( (2 * panel_size + 4 + NO_MARKER) * n * iword +
(panel_size + 1) * n * dword );
mem_usage->expansions = --no_expand;
@@ -165,16 +165,16 @@ int sQuerySpace(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage)
int
sLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz,
int panel_size, SuperMatrix *L, SuperMatrix *U, GlobalLU_t *Glu,
- int **iwork, float **dwork)
+ int **iwork, double **dwork)
{
int info, iword, dword;
SCformat *Lstore;
NCformat *Ustore;
int *xsup, *supno;
int *lsub, *xlsub;
- float *lusup;
+ double *lusup;
int *xlusup;
- float *ucol;
+ double *ucol;
int *usub, *xusub;
int nzlmax, nzumax, nzlumax;
int FILL = sp_ienv(6);
@@ -182,7 +182,7 @@ sLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz,
Glu->n = n;
no_expand = 0;
iword = sizeof(int);
- dword = sizeof(float);
+ dword = sizeof(double);
if ( !expanders )
expanders = (ExpHeader*)SUPERLU_MALLOC(NO_MEMTYPE * sizeof(ExpHeader));
@@ -220,8 +220,8 @@ sLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz,
xusub = (int *)suser_malloc((n+1) * iword, HEAD);
}
- lusup = (float *) sexpand( &nzlumax, LUSUP, 0, 0, Glu );
- ucol = (float *) sexpand( &nzumax, UCOL, 0, 0, Glu );
+ lusup = (double *) sexpand( &nzlumax, LUSUP, 0, 0, Glu );
+ ucol = (double *) sexpand( &nzumax, UCOL, 0, 0, Glu );
lsub = (int *) sexpand( &nzlmax, LSUB, 0, 0, Glu );
usub = (int *) sexpand( &nzumax, USUB, 0, 1, Glu );
@@ -241,8 +241,8 @@ sLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz,
printf("Not enough memory to perform factorization.\n");
return (smemory_usage(nzlmax, nzumax, nzlumax, n) + n);
}
- lusup = (float *) sexpand( &nzlumax, LUSUP, 0, 0, Glu );
- ucol = (float *) sexpand( &nzumax, UCOL, 0, 0, Glu );
+ lusup = (double *) sexpand( &nzlumax, LUSUP, 0, 0, Glu );
+ ucol = (double *) sexpand( &nzumax, UCOL, 0, 0, Glu );
lsub = (int *) sexpand( &nzlmax, LSUB, 0, 0, Glu );
usub = (int *) sexpand( &nzumax, USUB, 0, 1, Glu );
}
@@ -307,16 +307,16 @@ sLUMemInit(fact_t fact, void *work, int lwork, int m, int n, int annz,
returns the number of bytes allocated so far when failure occurred. */
int
sLUWorkInit(int m, int n, int panel_size, int **iworkptr,
- float **dworkptr, LU_space_t MemModel)
+ double **dworkptr, LU_space_t MemModel)
{
int isize, dsize, extra;
- float *old_ptr;
+ double *old_ptr;
int maxsuper = sp_ienv(3),
rowblk = sp_ienv(4);
isize = ( (2 * panel_size + 3 + NO_MARKER ) * m + n ) * sizeof(int);
dsize = (m * panel_size +
- NUM_TEMPV(m,panel_size,maxsuper,rowblk)) * sizeof(float);
+ NUM_TEMPV(m,panel_size,maxsuper,rowblk)) * sizeof(double);
if ( MemModel == SYSTEM )
*iworkptr = (int *) intCalloc(isize/sizeof(int));
@@ -328,13 +328,13 @@ sLUWorkInit(int m, int n, int panel_size, int **iworkptr,
}
if ( MemModel == SYSTEM )
- *dworkptr = (float *) SUPERLU_MALLOC(dsize);
+ *dworkptr = (double *) SUPERLU_MALLOC(dsize);
else {
- *dworkptr = (float *) suser_malloc(dsize, TAIL);
+ *dworkptr = (double *) suser_malloc(dsize, TAIL);
if ( NotDoubleAlign(*dworkptr) ) {
old_ptr = *dworkptr;
- *dworkptr = (float*) DoubleAlign(*dworkptr);
- *dworkptr = (float*) ((double*)*dworkptr - 1);
+ *dworkptr = (double*) DoubleAlign(*dworkptr);
+ *dworkptr = (double*) ((double*)*dworkptr - 1);
extra = (char*)old_ptr - (char*)*dworkptr;
#ifdef DEBUG
printf("sLUWorkInit: not aligned, extra %d\n", extra);
@@ -356,10 +356,10 @@ sLUWorkInit(int m, int n, int panel_size, int **iworkptr,
* Set up pointers for real working arrays.
*/
void
-sSetRWork(int m, int panel_size, float *dworkptr,
- float **dense, float **tempv)
+sSetRWork(int m, int panel_size, double *dworkptr,
+ double **dense, double **tempv)
{
- float zero = 0.0;
+ double zero = 0.0;
int maxsuper = sp_ienv(3),
rowblk = sp_ienv(4);
@@ -372,7 +372,7 @@ sSetRWork(int m, int panel_size, float *dworkptr,
/*
* Free the working storage used by factor routines.
*/
-void sLUWorkFree(int *iwork, float *dwork, GlobalLU_t *Glu)
+void sLUWorkFree(int *iwork, double *dwork, GlobalLU_t *Glu)
{
if ( Glu->MemModel == SYSTEM ) {
SUPERLU_FREE (iwork);
@@ -421,11 +421,11 @@ sLUMemXpand(int jcol,
switch ( mem_type ) {
case LUSUP:
- Glu->lusup = (float *) new_mem;
+ Glu->lusup = (double *) new_mem;
Glu->nzlumax = *maxlen;
break;
case UCOL:
- Glu->ucol = (float *) new_mem;
+ Glu->ucol = (double *) new_mem;
Glu->nzumax = *maxlen;
break;
case LSUB:
@@ -445,11 +445,11 @@ sLUMemXpand(int jcol,
void
-copy_mem_float(int howmany, void *old, void *new)
+copy_mem_double(int howmany, void *old, void *new)
{
register int i;
- float *dold = old;
- float *dnew = new;
+ double *dold = old;
+ double *dnew = new;
for (i = 0; i < howmany; i++) dnew[i] = dold[i];
}
@@ -466,8 +466,8 @@ void
GlobalLU_t *Glu /* modified - global LU data structures */
)
{
- float EXPAND = 1.5;
- float alpha;
+ double EXPAND = 1.5;
+ double alpha;
void *new_mem, *old_mem;
int new_len, tries, lword, extra, bytes_to_copy;
@@ -480,7 +480,7 @@ void
}
if ( type == LSUB || type == USUB ) lword = sizeof(int);
- else lword = sizeof(float);
+ else lword = sizeof(double);
if ( Glu->MemModel == SYSTEM ) {
new_mem = (void *) SUPERLU_MALLOC(new_len * lword);
@@ -501,7 +501,7 @@ void
if ( type == LSUB || type == USUB ) {
copy_mem_int(len_to_copy, expanders[type].mem, new_mem);
} else {
- copy_mem_float(len_to_copy, expanders[type].mem, new_mem);
+ copy_mem_double(len_to_copy, expanders[type].mem, new_mem);
}
SUPERLU_FREE (expanders[type].mem);
}
@@ -585,12 +585,12 @@ sStackCompress(GlobalLU_t *Glu)
register int iword, dword, ndim;
char *last, *fragment;
int *ifrom, *ito;
- float *dfrom, *dto;
+ double *dfrom, *dto;
int *xlsub, *lsub, *xusub, *usub, *xlusup;
- float *ucol, *lusup;
+ double *ucol, *lusup;
iword = sizeof(int);
- dword = sizeof(float);
+ dword = sizeof(double);
ndim = Glu->n;
xlsub = Glu->xlsub;
@@ -602,8 +602,8 @@ sStackCompress(GlobalLU_t *Glu)
lusup = Glu->lusup;
dfrom = ucol;
- dto = (float *)((char*)lusup + xlusup[ndim] * dword);
- copy_mem_float(xusub[ndim], dfrom, dto);
+ dto = (double *)((char*)lusup + xlusup[ndim] * dword);
+ copy_mem_double(xusub[ndim], dfrom, dto);
ucol = dto;
ifrom = lsub;
@@ -637,32 +637,32 @@ sStackCompress(GlobalLU_t *Glu)
* Allocate storage for original matrix A
*/
void
-sallocateA(int n, int nnz, float **a, int **asub, int **xa)
+sallocateA(int n, int nnz, double **a, int **asub, int **xa)
{
- *a = (float *) floatMalloc(nnz);
+ *a = (double *) doubleMalloc(nnz);
*asub = (int *) intMalloc(nnz);
*xa = (int *) intMalloc(n+1);
}
-float *floatMalloc(int n)
+double *doubleMalloc(int n)
{
- float *buf;
- buf = (float *) SUPERLU_MALLOC(n * sizeof(float));
+ double *buf;
+ buf = (double *) SUPERLU_MALLOC(n * sizeof(double));
if ( !buf ) {
- ABORT("SUPERLU_MALLOC failed for buf in floatMalloc()\n");
+ ABORT("SUPERLU_MALLOC failed for buf in doubleMalloc()\n");
}
return (buf);
}
-float *floatCalloc(int n)
+double *doubleCalloc(int n)
{
- float *buf;
+ double *buf;
register int i;
- float zero = 0.0;
- buf = (float *) SUPERLU_MALLOC(n * sizeof(float));
+ double zero = 0.0;
+ buf = (double *) SUPERLU_MALLOC(n * sizeof(double));
if ( !buf ) {
- ABORT("SUPERLU_MALLOC failed for buf in floatCalloc()\n");
+ ABORT("SUPERLU_MALLOC failed for buf in doubleCalloc()\n");
}
for (i = 0; i < n; ++i) buf[i] = zero;
return (buf);
@@ -675,7 +675,7 @@ int smemory_usage(const int nzlmax, const int nzumax,
register int iword, dword;
iword = sizeof(int);
- dword = sizeof(float);
+ dword = sizeof(double);
return (10 * n * iword +
nzlmax * iword + nzumax * (iword + dword) + nzlumax * dword);
diff --git a/intern/opennl/superlu/smyblas2.c b/intern/opennl/superlu/smyblas2.c
index 79f6a11bb6a..11e3b4b4761 100644
--- a/intern/opennl/superlu/smyblas2.c
+++ b/intern/opennl/superlu/smyblas2.c
@@ -25,17 +25,17 @@
*/
/* local prototypes*/
-void slsolve ( int, int, float *, float *);
-void susolve ( int, int, float *, float *);
-void smatvec ( int, int, int, float *, float *, float *);
+void slsolve ( int, int, double *, double *);
+void susolve ( int, int, double *, double *);
+void smatvec ( int, int, int, double *, double *, double *);
-void slsolve ( int ldm, int ncol, float *M, float *rhs )
+void slsolve ( int ldm, int ncol, double *M, double *rhs )
{
int k;
- float x0, x1, x2, x3, x4, x5, x6, x7;
- float *M0;
- register float *Mki0, *Mki1, *Mki2, *Mki3, *Mki4, *Mki5, *Mki6, *Mki7;
+ double x0, x1, x2, x3, x4, x5, x6, x7;
+ double *M0;
+ register double *Mki0, *Mki1, *Mki2, *Mki3, *Mki4, *Mki5, *Mki6, *Mki7;
register int firstcol = 0;
M0 = &M[0];
@@ -131,10 +131,10 @@ void
susolve ( ldm, ncol, M, rhs )
int ldm; /* in */
int ncol; /* in */
-float *M; /* in */
-float *rhs; /* modified */
+double *M; /* in */
+double *rhs; /* modified */
{
- float xj;
+ double xj;
int jcol, j, irow;
jcol = ncol - 1;
@@ -162,14 +162,14 @@ void smatvec ( ldm, nrow, ncol, M, vec, Mxvec )
int ldm; /* in -- leading dimension of M */
int nrow; /* in */
int ncol; /* in */
-float *M; /* in */
-float *vec; /* in */
-float *Mxvec; /* in/out */
+double *M; /* in */
+double *vec; /* in */
+double *Mxvec; /* in/out */
{
- float vi0, vi1, vi2, vi3, vi4, vi5, vi6, vi7;
- float *M0;
- register float *Mki0, *Mki1, *Mki2, *Mki3, *Mki4, *Mki5, *Mki6, *Mki7;
+ double vi0, vi1, vi2, vi3, vi4, vi5, vi6, vi7;
+ double *M0;
+ register double *Mki0, *Mki1, *Mki2, *Mki3, *Mki4, *Mki5, *Mki6, *Mki7;
register int firstcol = 0;
int k;
diff --git a/intern/opennl/superlu/spanel_bmod.c b/intern/opennl/superlu/spanel_bmod.c
index c9c17ea861d..5f150e640fd 100644
--- a/intern/opennl/superlu/spanel_bmod.c
+++ b/intern/opennl/superlu/spanel_bmod.c
@@ -29,8 +29,8 @@
/*
* Function prototypes
*/
-void slsolve(int, int, float *, float *);
-void smatvec(int, int, int, float *, float *, float *);
+void slsolve(int, int, double *, double *);
+void smatvec(int, int, int, double *, double *, double *);
extern void scheck_tempv();
void
@@ -39,8 +39,8 @@ spanel_bmod (
const int w, /* in */
const int jcol, /* in */
const int nseg, /* in */
- float *dense, /* out, of size n by w */
- float *tempv, /* working array */
+ double *dense, /* out, of size n by w */
+ double *tempv, /* working array */
int *segrep, /* in */
int *repfnz, /* in, of size n by w */
GlobalLU_t *Glu, /* modified */
@@ -71,13 +71,13 @@ spanel_bmod (
ftcs3 = _cptofcd("U", strlen("U"));
#endif
int incx = 1, incy = 1;
- float alpha, beta;
+ double alpha, beta;
#endif
register int k, ksub;
int fsupc, nsupc, nsupr, nrow;
int krep, krep_ind;
- float ukj, ukj1, ukj2;
+ double ukj, ukj1, ukj2;
int luptr, luptr1, luptr2;
int segsze;
int block_nrow; /* no of rows in a block row */
@@ -87,13 +87,13 @@ spanel_bmod (
register int jj; /* Index through each column in the panel */
int *xsup, *supno;
int *lsub, *xlsub;
- float *lusup;
+ double *lusup;
int *xlusup;
int *repfnz_col; /* repfnz[] for a column in the panel */
- float *dense_col; /* dense[] for a column in the panel */
- float *tempv1; /* Used in 1-D update */
- float *TriTmp, *MatvecTmp; /* used in 2-D update */
- float zero = 0.0;
+ double *dense_col; /* dense[] for a column in the panel */
+ double *tempv1; /* Used in 1-D update */
+ double *TriTmp, *MatvecTmp; /* used in 2-D update */
+ double zero = 0.0;
register int ldaTmp;
register int r_ind, r_hi;
static int first = 1, maxsuper, rowblk, colblk;
diff --git a/intern/opennl/superlu/spanel_dfs.c b/intern/opennl/superlu/spanel_dfs.c
index e49adf635b2..80e6814dde9 100644
--- a/intern/opennl/superlu/spanel_dfs.c
+++ b/intern/opennl/superlu/spanel_dfs.c
@@ -34,7 +34,7 @@ spanel_dfs (
SuperMatrix *A, /* in - original matrix */
int *perm_r, /* in */
int *nseg, /* out */
- float *dense, /* out */
+ double *dense, /* out */
int *panel_lsub, /* out */
int *segrep, /* out */
int *repfnz, /* out */
@@ -74,7 +74,7 @@ spanel_dfs (
*
*/
NCPformat *Astore;
- float *a;
+ double *a;
int *asub;
int *xa_begin, *xa_end;
int krep, chperm, chmark, chrep, oldrep, kchild, myfnz;
@@ -84,7 +84,7 @@ spanel_dfs (
int *marker1; /* marker1[jj] >= jcol if vertex jj was visited
by a previous column within this panel. */
int *repfnz_col; /* start of each column in the panel */
- float *dense_col; /* start of each column in the panel */
+ double *dense_col; /* start of each column in the panel */
int nextl_col; /* next available position in panel_lsub[*,jj] */
int *xsup, *supno;
int *lsub, *xlsub;
diff --git a/intern/opennl/superlu/spivotL.c b/intern/opennl/superlu/spivotL.c
index 3d5174e0b90..1a0302d0101 100644
--- a/intern/opennl/superlu/spivotL.c
+++ b/intern/opennl/superlu/spivotL.c
@@ -31,7 +31,7 @@
int
spivotL(
const int jcol, /* in */
- const float u, /* in - diagonal pivoting threshold */
+ const double u, /* in - diagonal pivoting threshold */
int *usepr, /* re-use the pivot sequence given by perm_r/iperm_r */
int *perm_r, /* may be modified */
int *iperm_r, /* in - inverse of perm_r */
@@ -67,14 +67,14 @@ spivotL(
int nsupr; /* no of rows in the supernode */
int lptr; /* points to the starting subscript of the supernode */
int pivptr, old_pivptr, diag, diagind;
- float pivmax, rtemp, thresh;
- float temp;
- float *lu_sup_ptr;
- float *lu_col_ptr;
+ double pivmax, rtemp, thresh;
+ double temp;
+ double *lu_sup_ptr;
+ double *lu_col_ptr;
int *lsub_ptr;
int isub, icol, k, itemp;
int *lsub, *xlsub;
- float *lusup;
+ double *lusup;
int *xlusup;
flops_t *ops = stat->ops;
diff --git a/intern/opennl/superlu/spruneL.c b/intern/opennl/superlu/spruneL.c
index e6603f1d42a..3cf29658596 100644
--- a/intern/opennl/superlu/spruneL.c
+++ b/intern/opennl/superlu/spruneL.c
@@ -45,13 +45,13 @@ spruneL(
* contains the current pivot row "pivrow"
*
*/
- float utemp;
+ double utemp;
int jsupno, irep, irep1, kmin, kmax, krow, movnum;
int i, ktemp, minloc, maxloc;
int do_prune; /* logical variable */
int *xsup, *supno;
int *lsub, *xlsub;
- float *lusup;
+ double *lusup;
int *xlusup;
xsup = Glu->xsup;
diff --git a/intern/opennl/superlu/ssnode_bmod.c b/intern/opennl/superlu/ssnode_bmod.c
index 21b236feedd..9533373f212 100644
--- a/intern/opennl/superlu/ssnode_bmod.c
+++ b/intern/opennl/superlu/ssnode_bmod.c
@@ -24,8 +24,8 @@
#include "ssp_defs.h"
-void slsolve(int, int, float*, float*);
-void smatvec(int, int, int, float*, float*, float*);
+void slsolve(int, int, double*, double*);
+void smatvec(int, int, int, double*, double*, double*);
/*
* Performs numeric block updates within the relaxed snode.
@@ -34,8 +34,8 @@ int
ssnode_bmod (
const int jcol, /* in */
const int fsupc, /* in */
- float *dense, /* in */
- float *tempv, /* working array */
+ double *dense, /* in */
+ double *tempv, /* working array */
GlobalLU_t *Glu, /* modified */
SuperLUStat_t *stat /* output */
)
@@ -47,14 +47,14 @@ ssnode_bmod (
ftcs3 = _cptofcd("U", strlen("U"));
#endif
int incx = 1, incy = 1;
- float alpha = -1.0, beta = 1.0;
+ double alpha = -1.0, beta = 1.0;
#endif
int luptr, nsupc, nsupr, nrow;
int isub, irow, i, iptr;
register int ufirst, nextlu;
int *lsub, *xlsub;
- float *lusup;
+ double *lusup;
int *xlusup;
flops_t *ops = stat->ops;
diff --git a/intern/opennl/superlu/ssp_blas2.c b/intern/opennl/superlu/ssp_blas2.c
index d8889cd4b9d..9215d48dc09 100644
--- a/intern/opennl/superlu/ssp_blas2.c
+++ b/intern/opennl/superlu/ssp_blas2.c
@@ -19,14 +19,14 @@
/*
* Function prototypes
*/
-void susolve(int, int, float*, float*);
-void slsolve(int, int, float*, float*);
-void smatvec(int, int, int, float*, float*, float*);
-int strsv_(char*, char*, char*, int*, float*, int*, float*, int*);
+void susolve(int, int, double*, double*);
+void slsolve(int, int, double*, double*);
+void smatvec(int, int, int, double*, double*, double*);
+int strsv_(char*, char*, char*, int*, double*, int*, double*, int*);
int
sp_strsv(char *uplo, char *trans, char *diag, SuperMatrix *L,
- SuperMatrix *U, float *x, SuperLUStat_t *stat, int *info)
+ SuperMatrix *U, double *x, SuperLUStat_t *stat, int *info)
{
/*
* Purpose
@@ -71,7 +71,7 @@ sp_strsv(char *uplo, char *trans, char *diag, SuperMatrix *L,
* The factor U from the factorization Pr*A*Pc=L*U.
* U has types: Stype = NC, Dtype = SLU_S, Mtype = TRU.
*
- * x - (input/output) float*
+ * x - (input/output) double*
* Before entry, the incremented array X must contain the n
* element right-hand side vector b. On exit, X is overwritten
* with the solution vector x.
@@ -87,12 +87,12 @@ sp_strsv(char *uplo, char *trans, char *diag, SuperMatrix *L,
#endif
SCformat *Lstore;
NCformat *Ustore;
- float *Lval, *Uval;
+ double *Lval, *Uval;
int incx = 1;
int nrow;
int fsupc, nsupr, nsupc, luptr, istart, irow;
int i, k, iptr, jcol;
- float *work;
+ double *work;
flops_t solve_ops;
/* Test the input parameters */
@@ -115,7 +115,7 @@ sp_strsv(char *uplo, char *trans, char *diag, SuperMatrix *L,
Uval = Ustore->nzval;
solve_ops = 0;
- if ( !(work = floatCalloc(L->nrow)) )
+ if ( !(work = doubleCalloc(L->nrow)) )
ABORT("Malloc fails for work in sp_strsv().");
if ( lsame_(trans, "N") ) { /* Form x := inv(A)*x. */
@@ -306,8 +306,8 @@ sp_strsv(char *uplo, char *trans, char *diag, SuperMatrix *L,
int
-sp_sgemv(char *trans, float alpha, SuperMatrix *A, float *x,
- int incx, float beta, float *y, int incy)
+sp_sgemv(char *trans, double alpha, SuperMatrix *A, double *x,
+ int incx, double beta, double *y, int incy)
{
/* Purpose
=======
@@ -327,7 +327,7 @@ sp_sgemv(char *trans, float alpha, SuperMatrix *A, float *x,
TRANS = 'T' or 't' y := alpha*A'*x + beta*y.
TRANS = 'C' or 'c' y := alpha*A'*x + beta*y.
- ALPHA - (input) float
+ ALPHA - (input) double
On entry, ALPHA specifies the scalar alpha.
A - (input) SuperMatrix*
@@ -336,7 +336,7 @@ sp_sgemv(char *trans, float alpha, SuperMatrix *A, float *x,
Stype = NC or NCP; Dtype = SLU_S; Mtype = GE.
In the future, more general A can be handled.
- X - (input) float*, array of DIMENSION at least
+ X - (input) double*, array of DIMENSION at least
( 1 + ( n - 1 )*abs( INCX ) ) when TRANS = 'N' or 'n'
and at least
( 1 + ( m - 1 )*abs( INCX ) ) otherwise.
@@ -347,11 +347,11 @@ sp_sgemv(char *trans, float alpha, SuperMatrix *A, float *x,
On entry, INCX specifies the increment for the elements of
X. INCX must not be zero.
- BETA - (input) float
+ BETA - (input) double
On entry, BETA specifies the scalar beta. When BETA is
supplied as zero then Y need not be set on input.
- Y - (output) float*, array of DIMENSION at least
+ Y - (output) double*, array of DIMENSION at least
( 1 + ( m - 1 )*abs( INCY ) ) when TRANS = 'N' or 'n'
and at least
( 1 + ( n - 1 )*abs( INCY ) ) otherwise.
@@ -368,9 +368,9 @@ sp_sgemv(char *trans, float alpha, SuperMatrix *A, float *x,
/* Local variables */
NCformat *Astore;
- float *Aval;
+ double *Aval;
int info;
- float temp;
+ double temp;
int lenx, leny, i, j, irow;
int iy, jx, jy, kx, ky;
int notran;
diff --git a/intern/opennl/superlu/ssp_blas3.c b/intern/opennl/superlu/ssp_blas3.c
index 789635ceec4..aeb51b0c1ca 100644
--- a/intern/opennl/superlu/ssp_blas3.c
+++ b/intern/opennl/superlu/ssp_blas3.c
@@ -20,8 +20,8 @@
int
sp_sgemm(char *transa, int n,
- float alpha, SuperMatrix *A, float *b, int ldb,
- float beta, float *c, int ldc)
+ double alpha, SuperMatrix *A, double *b, int ldb,
+ double beta, double *c, int ldc)
{
/* Purpose
=======
@@ -74,7 +74,7 @@ sp_sgemm(char *transa, int n,
be at least zero.
Unchanged on exit.
- ALPHA - (input) float
+ ALPHA - (input) double
On entry, ALPHA specifies the scalar alpha.
A - (input) SuperMatrix*
@@ -96,7 +96,7 @@ sp_sgemm(char *transa, int n,
in the calling (sub) program. LDB must be at least max( 1, n ).
Unchanged on exit.
- BETA - (input) float
+ BETA - (input) double
On entry, BETA specifies the scalar beta. When BETA is
supplied as zero then C need not be set on input.
diff --git a/intern/opennl/superlu/ssp_defs.h b/intern/opennl/superlu/ssp_defs.h
index 118e3f16eb1..5110fc5ad69 100644
--- a/intern/opennl/superlu/ssp_defs.h
+++ b/intern/opennl/superlu/ssp_defs.h
@@ -88,9 +88,9 @@ typedef struct {
int *supno;
int *lsub; /* compressed L subscripts */
int *xlsub;
- float *lusup; /* L supernodes */
+ double *lusup; /* L supernodes */
int *xlusup;
- float *ucol; /* U columns */
+ double *ucol; /* U columns */
int *usub;
int *xusub;
int nzlmax; /* current max size of lsub */
@@ -101,8 +101,8 @@ typedef struct {
} GlobalLU_t;
typedef struct {
- float for_lu;
- float total_needed;
+ double for_lu;
+ double total_needed;
int expansions;
} mem_usage_t;
@@ -116,61 +116,61 @@ sgssv(superlu_options_t *, SuperMatrix *, int *, int *, SuperMatrix *,
SuperMatrix *, SuperMatrix *, SuperLUStat_t *, int *);
extern void
sgssvx(superlu_options_t *, SuperMatrix *, int *, int *, int *,
- char *, float *, float *, SuperMatrix *, SuperMatrix *,
+ char *, double *, double *, SuperMatrix *, SuperMatrix *,
void *, int, SuperMatrix *, SuperMatrix *,
- float *, float *, float *, float *,
+ double *, double *, double *, double *,
mem_usage_t *, SuperLUStat_t *, int *);
/* Supernodal LU factor related */
extern void
-sCreate_CompCol_Matrix(SuperMatrix *, int, int, int, float *,
+sCreate_CompCol_Matrix(SuperMatrix *, int, int, int, double *,
int *, int *, Stype_t, Dtype_t, Mtype_t);
extern void
-sCreate_CompRow_Matrix(SuperMatrix *, int, int, int, float *,
+sCreate_CompRow_Matrix(SuperMatrix *, int, int, int, double *,
int *, int *, Stype_t, Dtype_t, Mtype_t);
extern void
sCopy_CompCol_Matrix(SuperMatrix *, SuperMatrix *);
extern void
-sCreate_Dense_Matrix(SuperMatrix *, int, int, float *, int,
+sCreate_Dense_Matrix(SuperMatrix *, int, int, double *, int,
Stype_t, Dtype_t, Mtype_t);
extern void
-sCreate_SuperNode_Matrix(SuperMatrix *, int, int, int, float *,
+sCreate_SuperNode_Matrix(SuperMatrix *, int, int, int, double *,
int *, int *, int *, int *, int *,
Stype_t, Dtype_t, Mtype_t);
extern void
-sCopy_Dense_Matrix(int, int, float *, int, float *, int);
+sCopy_Dense_Matrix(int, int, double *, int, double *, int);
extern void countnz (const int, int *, int *, int *, GlobalLU_t *);
extern void fixupL (const int, const int *, GlobalLU_t *);
-extern void sallocateA (int, int, float **, int **, int **);
+extern void sallocateA (int, int, double **, int **, int **);
extern void sgstrf (superlu_options_t*, SuperMatrix*,
int, int, int*, void *, int, int *, int *,
SuperMatrix *, SuperMatrix *, SuperLUStat_t*, int *);
extern int ssnode_dfs (const int, const int, const int *, const int *,
const int *, int *, int *, GlobalLU_t *);
-extern int ssnode_bmod (const int, const int, float *,
- float *, GlobalLU_t *, SuperLUStat_t*);
+extern int ssnode_bmod (const int, const int, double *,
+ double *, GlobalLU_t *, SuperLUStat_t*);
extern void spanel_dfs (const int, const int, const int, SuperMatrix *,
- int *, int *, float *, int *, int *, int *,
+ int *, int *, double *, int *, int *, int *,
int *, int *, int *, int *, GlobalLU_t *);
extern void spanel_bmod (const int, const int, const int, const int,
- float *, float *, int *, int *,
+ double *, double *, int *, int *,
GlobalLU_t *, SuperLUStat_t*);
extern int scolumn_dfs (const int, const int, int *, int *, int *, int *,
int *, int *, int *, int *, int *, GlobalLU_t *);
-extern int scolumn_bmod (const int, const int, float *,
- float *, int *, int *, int,
+extern int scolumn_bmod (const int, const int, double *,
+ double *, int *, int *, int,
GlobalLU_t *, SuperLUStat_t*);
extern int scopy_to_ucol (int, int, int *, int *, int *,
- float *, GlobalLU_t *);
-extern int spivotL (const int, const float, int *, int *,
+ double *, GlobalLU_t *);
+extern int spivotL (const int, const double, int *, int *,
int *, int *, int *, GlobalLU_t *, SuperLUStat_t*);
extern void spruneL (const int, const int *, const int, const int,
const int *, const int *, int *, GlobalLU_t *);
-extern void sreadmt (int *, int *, int *, float **, int **, int **);
-extern void sGenXtrue (int, int, float *, int);
-extern void sFillRHS (trans_t, int, float *, int, SuperMatrix *,
+extern void sreadmt (int *, int *, int *, double **, int **, int **);
+extern void sGenXtrue (int, int, double *, int);
+extern void sFillRHS (trans_t, int, double *, int, SuperMatrix *,
SuperMatrix *);
extern void sgstrs (trans_t, SuperMatrix *, SuperMatrix *, int *, int *,
SuperMatrix *, SuperLUStat_t*, int *);
@@ -178,56 +178,56 @@ extern void sgstrs (trans_t, SuperMatrix *, SuperMatrix *, int *, int *,
/* Driver related */
-extern void sgsequ (SuperMatrix *, float *, float *, float *,
- float *, float *, int *);
-extern void slaqgs (SuperMatrix *, float *, float *, float,
- float, float, char *);
+extern void sgsequ (SuperMatrix *, double *, double *, double *,
+ double *, double *, int *);
+extern void slaqgs (SuperMatrix *, double *, double *, double,
+ double, double, char *);
extern void sgscon (char *, SuperMatrix *, SuperMatrix *,
- float, float *, SuperLUStat_t*, int *);
-extern float sPivotGrowth(int, SuperMatrix *, int *,
+ double, double *, SuperLUStat_t*, int *);
+extern double sPivotGrowth(int, SuperMatrix *, int *,
SuperMatrix *, SuperMatrix *);
extern void sgsrfs (trans_t, SuperMatrix *, SuperMatrix *,
- SuperMatrix *, int *, int *, char *, float *,
- float *, SuperMatrix *, SuperMatrix *,
- float *, float *, SuperLUStat_t*, int *);
+ SuperMatrix *, int *, int *, char *, double *,
+ double *, SuperMatrix *, SuperMatrix *,
+ double *, double *, SuperLUStat_t*, int *);
extern int sp_strsv (char *, char *, char *, SuperMatrix *,
- SuperMatrix *, float *, SuperLUStat_t*, int *);
-extern int sp_sgemv (char *, float, SuperMatrix *, float *,
- int, float, float *, int);
+ SuperMatrix *, double *, SuperLUStat_t*, int *);
+extern int sp_sgemv (char *, double, SuperMatrix *, double *,
+ int, double, double *, int);
-extern int sp_sgemm (char *, int, float,
- SuperMatrix *, float *, int, float,
- float *, int);
+extern int sp_sgemm (char *, int, double,
+ SuperMatrix *, double *, int, double,
+ double *, int);
/* Memory-related */
extern int sLUMemInit (fact_t, void *, int, int, int, int, int,
SuperMatrix *, SuperMatrix *,
- GlobalLU_t *, int **, float **);
-extern void sSetRWork (int, int, float *, float **, float **);
-extern void sLUWorkFree (int *, float *, GlobalLU_t *);
+ GlobalLU_t *, int **, double **);
+extern void sSetRWork (int, int, double *, double **, double **);
+extern void sLUWorkFree (int *, double *, GlobalLU_t *);
extern int sLUMemXpand (int, int, MemType, int *, GlobalLU_t *);
-extern float *floatMalloc(int);
-extern float *floatCalloc(int);
+extern double *doubleMalloc(int);
+extern double *doubleCalloc(int);
extern int smemory_usage(const int, const int, const int, const int);
extern int sQuerySpace (SuperMatrix *, SuperMatrix *, mem_usage_t *);
/* Auxiliary routines */
-extern void sreadhb(int *, int *, int *, float **, int **, int **);
-extern void sCompRow_to_CompCol(int, int, int, float*, int*, int*,
- float **, int **, int **);
-extern void sfill (float *, int, float);
-extern void sinf_norm_error (int, SuperMatrix *, float *);
+extern void sreadhb(int *, int *, int *, double **, int **, int **);
+extern void sCompRow_to_CompCol(int, int, int, double*, int*, int*,
+ double **, int **, int **);
+extern void sfill (double *, int, double);
+extern void sinf_norm_error (int, SuperMatrix *, double *);
extern void PrintPerf (SuperMatrix *, SuperMatrix *, mem_usage_t *,
- float, float, float *, float *, char *);
+ double, double, double *, double *, char *);
/* Routines for debugging */
extern void sPrint_CompCol_Matrix(char *, SuperMatrix *);
extern void sPrint_SuperNode_Matrix(char *, SuperMatrix *);
extern void sPrint_Dense_Matrix(char *, SuperMatrix *);
extern void print_lu_col(char *, int, int, int *, GlobalLU_t *);
-extern void check_tempv(int, float *);
+extern void check_tempv(int, double *);
extern int print_int_vec(char *what, int n, int *vec);
extern int sp_symetree(int *acolst, int *acolend, int *arow, int n, int *parent);
diff --git a/intern/opennl/superlu/strsv.c b/intern/opennl/superlu/strsv.c
index da904ba3e9d..a34f5fb38a1 100644
--- a/intern/opennl/superlu/strsv.c
+++ b/intern/opennl/superlu/strsv.c
@@ -1,17 +1,17 @@
/** \file opennl/superlu/strsv.c
* \ingroup opennl
*/
-int strsv_(char *, char *, char *, int *, float *, int *, float *, int *);
+int strsv_(char *, char *, char *, int *, double *, int *, double *, int *);
/* Subroutine */ int strsv_(char *uplo, char *trans, char *diag, int *n,
- float *a, int *lda, float *x, int *incx)
+ double *a, int *lda, double *x, int *incx)
{
/* Local variables */
static int info;
- static float temp;
+ static double temp;
static int i, j;
extern int lsame_(char *, char *);
static int ix, jx, kx;
diff --git a/intern/opennl/superlu/sutil.c b/intern/opennl/superlu/sutil.c
index a77e87b9c65..52728e47f56 100644
--- a/intern/opennl/superlu/sutil.c
+++ b/intern/opennl/superlu/sutil.c
@@ -27,15 +27,15 @@
/* prototypes */
void sprint_lu_col(char *msg, int jcol, int pivrow, int *xprune, GlobalLU_t *Glu);
-void scheck_tempv(int n, float *tempv);
-void sPrintPerf(SuperMatrix *, SuperMatrix *, mem_usage_t *,float , float ,
- float *, float *, char *, SuperLUStat_t *);
-int print_float_vec(char *what, int n, float *vec);
+void scheck_tempv(int n, double *tempv);
+void sPrintPerf(SuperMatrix *, SuperMatrix *, mem_usage_t *,double , double ,
+ double *, double *, char *, SuperLUStat_t *);
+int print_double_vec(char *what, int n, double *vec);
/* ********** */
void
sCreate_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz,
- float *nzval, int *rowind, int *colptr,
+ double *nzval, int *rowind, int *colptr,
Stype_t stype, Dtype_t dtype, Mtype_t mtype)
{
NCformat *Astore;
@@ -56,7 +56,7 @@ sCreate_CompCol_Matrix(SuperMatrix *A, int m, int n, int nnz,
void
sCreate_CompRow_Matrix(SuperMatrix *A, int m, int n, int nnz,
- float *nzval, int *colind, int *rowptr,
+ double *nzval, int *colind, int *rowptr,
Stype_t stype, Dtype_t dtype, Mtype_t mtype)
{
NRformat *Astore;
@@ -91,14 +91,14 @@ sCopy_CompCol_Matrix(SuperMatrix *A, SuperMatrix *B)
Bstore = (NCformat *) B->Store;
Bstore->nnz = nnz = Astore->nnz;
for (i = 0; i < nnz; ++i)
- ((float *)Bstore->nzval)[i] = ((float *)Astore->nzval)[i];
+ ((double *)Bstore->nzval)[i] = ((double *)Astore->nzval)[i];
for (i = 0; i < nnz; ++i) Bstore->rowind[i] = Astore->rowind[i];
for (i = 0; i <= ncol; ++i) Bstore->colptr[i] = Astore->colptr[i];
}
void
-sCreate_Dense_Matrix(SuperMatrix *X, int m, int n, float *x, int ldx,
+sCreate_Dense_Matrix(SuperMatrix *X, int m, int n, double *x, int ldx,
Stype_t stype, Dtype_t dtype, Mtype_t mtype)
{
DNformat *Xstore;
@@ -112,12 +112,12 @@ sCreate_Dense_Matrix(SuperMatrix *X, int m, int n, float *x, int ldx,
if ( !(X->Store) ) ABORT("SUPERLU_MALLOC fails for X->Store");
Xstore = (DNformat *) X->Store;
Xstore->lda = ldx;
- Xstore->nzval = (float *) x;
+ Xstore->nzval = (double *) x;
}
void
-sCopy_Dense_Matrix(int M, int N, float *X, int ldx,
- float *Y, int ldy)
+sCopy_Dense_Matrix(int M, int N, double *X, int ldx,
+ double *Y, int ldy)
{
/*
*
@@ -135,7 +135,7 @@ sCopy_Dense_Matrix(int M, int N, float *X, int ldx,
void
sCreate_SuperNode_Matrix(SuperMatrix *L, int m, int n, int nnz,
- float *nzval, int *nzval_colptr, int *rowind,
+ double *nzval, int *nzval_colptr, int *rowind,
int *rowind_colptr, int *col_to_sup, int *sup_to_col,
Stype_t stype, Dtype_t dtype, Mtype_t mtype)
{
@@ -166,14 +166,14 @@ sCreate_SuperNode_Matrix(SuperMatrix *L, int m, int n, int nnz,
*/
void
sCompRow_to_CompCol(int m, int n, int nnz,
- float *a, int *colind, int *rowptr,
- float **at, int **rowind, int **colptr)
+ double *a, int *colind, int *rowptr,
+ double **at, int **rowind, int **colptr)
{
register int i, j, col, relpos;
int *marker;
/* Allocate storage for another copy of the matrix. */
- *at = (float *) floatMalloc(nnz);
+ *at = (double *) doubleMalloc(nnz);
*rowind = (int *) intMalloc(nnz);
*colptr = (int *) intMalloc(n+1);
marker = (int *) intCalloc(n);
@@ -207,13 +207,13 @@ sPrint_CompCol_Matrix(char *what, SuperMatrix *A)
{
NCformat *Astore;
register int i,n;
- float *dp;
+ double *dp;
printf("\nCompCol matrix %s:\n", what);
printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype);
n = A->ncol;
Astore = (NCformat *) A->Store;
- dp = (float *) Astore->nzval;
+ dp = (double *) Astore->nzval;
printf("nrow %d, ncol %d, nnz %d\n", A->nrow,A->ncol,Astore->nnz);
printf("nzval: ");
for (i = 0; i < Astore->colptr[n]; ++i) printf("%f ", dp[i]);
@@ -230,14 +230,14 @@ sPrint_SuperNode_Matrix(char *what, SuperMatrix *A)
{
SCformat *Astore;
register int i, j, k, c, d, n, nsup;
- float *dp;
+ double *dp;
int *col_to_sup, *sup_to_col, *rowind, *rowind_colptr;
printf("\nSuperNode matrix %s:\n", what);
printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype);
n = A->ncol;
Astore = (SCformat *) A->Store;
- dp = (float *) Astore->nzval;
+ dp = (double *) Astore->nzval;
col_to_sup = Astore->col_to_sup;
sup_to_col = Astore->sup_to_col;
rowind_colptr = Astore->rowind_colptr;
@@ -279,12 +279,12 @@ sPrint_Dense_Matrix(char *what, SuperMatrix *A)
{
DNformat *Astore;
register int i;
- float *dp;
+ double *dp;
printf("\nDense matrix %s:\n", what);
printf("Stype %d, Dtype %d, Mtype %d\n", A->Stype,A->Dtype,A->Mtype);
Astore = (DNformat *) A->Store;
- dp = (float *) Astore->nzval;
+ dp = (double *) Astore->nzval;
printf("nrow %d, ncol %d, lda %d\n", A->nrow,A->ncol,Astore->lda);
printf("\nnzval: ");
for (i = 0; i < A->nrow; ++i) printf("%f ", dp[i]);
@@ -301,9 +301,9 @@ sprint_lu_col(char *msg, int jcol, int pivrow, int *xprune, GlobalLU_t *Glu)
int i, k, fsupc;
int *xsup, *supno;
int *xlsub, *lsub;
- float *lusup;
+ double *lusup;
int *xlusup;
- float *ucol;
+ double *ucol;
int *usub, *xusub;
xsup = Glu->xsup;
@@ -339,7 +339,7 @@ sprint_lu_col(char *msg, int jcol, int pivrow, int *xprune, GlobalLU_t *Glu)
* Check whether tempv[] == 0. This should be true before and after
* calling any numeric routines, i.e., "panel_bmod" and "column_bmod".
*/
-void scheck_tempv(int n, float *tempv)
+void scheck_tempv(int n, double *tempv)
{
int i;
@@ -354,12 +354,12 @@ void scheck_tempv(int n, float *tempv)
void
-sGenXtrue(int n, int nrhs, float *x, int ldx)
+sGenXtrue(int n, int nrhs, double *x, int ldx)
{
int i, j;
for (j = 0; j < nrhs; ++j)
for (i = 0; i < n; ++i) {
- x[i + j*ldx] = 1.0;/* + (float)(i+1.)/n;*/
+ x[i + j*ldx] = 1.0;/* + (double)(i+1.)/n;*/
}
}
@@ -367,13 +367,13 @@ sGenXtrue(int n, int nrhs, float *x, int ldx)
* Let rhs[i] = sum of i-th row of A, so the solution vector is all 1's
*/
void
-sFillRHS(trans_t trans, int nrhs, float *x, int ldx,
+sFillRHS(trans_t trans, int nrhs, double *x, int ldx,
SuperMatrix *A, SuperMatrix *B)
{
DNformat *Bstore;
- float *rhs;
- float one = 1.0;
- float zero = 0.0;
+ double *rhs;
+ double one = 1.0;
+ double zero = 0.0;
int ldc;
char transc[1];
@@ -390,10 +390,10 @@ sFillRHS(trans_t trans, int nrhs, float *x, int ldx,
}
/*
- * Fills a float precision array with a given value.
+ * Fills a double precision array with a given value.
*/
void
-sfill(float *a, int alen, float dval)
+sfill(double *a, int alen, double dval)
{
register int i;
for (i = 0; i < alen; i++) a[i] = dval;
@@ -404,11 +404,11 @@ sfill(float *a, int alen, float dval)
/*
* Check the inf-norm of the error vector
*/
-void sinf_norm_error(int nrhs, SuperMatrix *X, float *xtrue)
+void sinf_norm_error(int nrhs, SuperMatrix *X, double *xtrue)
{
DNformat *Xstore;
- float err, xnorm;
- float *Xmat, *soln_work;
+ double err, xnorm;
+ double *Xmat, *soln_work;
int i, j;
Xstore = X->Store;
@@ -431,8 +431,8 @@ void sinf_norm_error(int nrhs, SuperMatrix *X, float *xtrue)
/* Print performance of the code. */
void
sPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage,
- float rpg, float rcond, float *ferr,
- float *berr, char *equed, SuperLUStat_t *stat)
+ double rpg, double rcond, double *ferr,
+ double *berr, char *equed, SuperLUStat_t *stat)
{
SCformat *Lstore;
NCformat *Ustore;
@@ -475,7 +475,7 @@ sPrintPerf(SuperMatrix *L, SuperMatrix *U, mem_usage_t *mem_usage,
-int print_float_vec(char *what, int n, float *vec)
+int print_double_vec(char *what, int n, double *vec)
{
int i;
printf("%s: n %d\n", what, n);
diff --git a/intern/opennl/superlu/util.c b/intern/opennl/superlu/util.c
index 7339bbc623a..96f404d886b 100644
--- a/intern/opennl/superlu/util.c
+++ b/intern/opennl/superlu/util.c
@@ -28,8 +28,8 @@
/* prototypes */
flops_t LUFactFlops(SuperLUStat_t *stat);
flops_t LUSolveFlops(SuperLUStat_t *stat);
-float SpaSize(int n, int np, float sum_npw);
-float DenseSize(int n, float sum_nw);
+double SpaSize(int n, int np, double sum_npw);
+double DenseSize(int n, double sum_nw);
/*
* Global statistics variale
@@ -332,27 +332,27 @@ void super_stats(int nsuper, int *xsup)
for (i = 0; i <= nsuper; i++) {
isize = xsup[i+1] - xsup[i];
- whichb = (float) isize / max_sup_size * NBUCKS;
+ whichb = (double) isize / max_sup_size * NBUCKS;
if (whichb >= NBUCKS) whichb = NBUCKS - 1;
bucket[whichb]++;
}
printf("\tHistogram of supernode sizes:\n");
for (i = 0; i < NBUCKS; i++) {
- bl = (float) i * max_sup_size / NBUCKS;
- bh = (float) (i+1) * max_sup_size / NBUCKS;
+ bl = (double) i * max_sup_size / NBUCKS;
+ bh = (double) (i+1) * max_sup_size / NBUCKS;
printf("\tsnode: %d-%d\t\t%d\n", bl+1, bh, bucket[i]);
}
}
-float SpaSize(int n, int np, float sum_npw)
+double SpaSize(int n, int np, double sum_npw)
{
return (sum_npw*8 + np*8 + n*4)/1024.;
}
-float DenseSize(int n, float sum_nw)
+double DenseSize(int n, double sum_nw)
{
return (sum_nw*8 + n*8)/1024.;;
}
diff --git a/intern/opennl/superlu/util.h b/intern/opennl/superlu/util.h
index c4c478cec2b..da9a8dbe4e3 100644
--- a/intern/opennl/superlu/util.h
+++ b/intern/opennl/superlu/util.h
@@ -97,7 +97,7 @@ typedef enum {
RCOND, /* estimate reciprocal condition number */
SOLVE, /* forward and back solves */
REFINE, /* perform iterative refinement */
- SLU_FLOAT, /* time spent in floating-point operations */
+ SLU_FLOAT, /* time spent in doubleing-point operations */
TRSV, /* fraction of FACT spent in xTRSV */
GEMV, /* fraction of FACT spent in xGEMV */
FERR, /* estimate error bounds after iterative refinement */
@@ -108,7 +108,7 @@ typedef enum {
/***********************************************************************
* Type definitions
***********************************************************************/
-typedef float flops_t;
+typedef double flops_t;
typedef unsigned char Logical;
/*
diff --git a/release/datafiles/blender_icons.svg b/release/datafiles/blender_icons.svg
index 4a1e2cd1d9a..f7dc50431c7 100644
--- a/release/datafiles/blender_icons.svg
+++ b/release/datafiles/blender_icons.svg
@@ -28399,26 +28399,9 @@
</dc:publisher>
<dc:coverage />
<cc:license
- rdf:resource="http://creativecommons.org/licenses/by-nc-sa/3.0/" />
- <dc:description>This content is under CC Attribution-NonCommercial ShareAlike licence 3.0 as long as it's used for Blender 3D GUI. Any other uses are not allowed.</dc:description>
+ rdf:resource="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html" />
+ <dc:description>GNU General Public License, version 2 or later.</dc:description>
</cc:Work>
- <cc:License
- rdf:about="http://creativecommons.org/licenses/by-nc-sa/3.0/">
- <cc:permits
- rdf:resource="http://creativecommons.org/ns#Reproduction" />
- <cc:permits
- rdf:resource="http://creativecommons.org/ns#Distribution" />
- <cc:requires
- rdf:resource="http://creativecommons.org/ns#Notice" />
- <cc:requires
- rdf:resource="http://creativecommons.org/ns#Attribution" />
- <cc:prohibits
- rdf:resource="http://creativecommons.org/ns#CommercialUse" />
- <cc:permits
- rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
- <cc:requires
- rdf:resource="http://creativecommons.org/ns#ShareAlike" />
- </cc:License>
</rdf:RDF>
</metadata>
<g
diff --git a/release/datafiles/locale b/release/datafiles/locale
-Subproject 919eb683bd2c5a2e626bcdb78f5fd5c048a70fd
+Subproject 841b1b9f494b6f980da4e244bbd86ecb8a8ac0b
diff --git a/release/datafiles/prvicons.svg b/release/datafiles/prvicons.svg
index 4e7bac725bd..e0894ff2dc8 100644
--- a/release/datafiles/prvicons.svg
+++ b/release/datafiles/prvicons.svg
@@ -17956,26 +17956,9 @@
</dc:publisher>
<dc:coverage />
<cc:license
- rdf:resource="http://creativecommons.org/licenses/by-nc-sa/3.0/" />
- <dc:description>This content is under CC Attribution-NonCommercial ShareAlike licence 3.0 as long as it's used for Blender 3D GUI. Any other uses are not allowed.</dc:description>
+ rdf:resource="http://www.gnu.org/licenses/old-licenses/gpl-2.0.html" />
+ <dc:description>GNU General Public License, version 2 or later.</dc:description>
</cc:Work>
- <cc:License
- rdf:about="http://creativecommons.org/licenses/by-nc-sa/3.0/">
- <cc:permits
- rdf:resource="http://creativecommons.org/ns#Reproduction" />
- <cc:permits
- rdf:resource="http://creativecommons.org/ns#Distribution" />
- <cc:requires
- rdf:resource="http://creativecommons.org/ns#Notice" />
- <cc:requires
- rdf:resource="http://creativecommons.org/ns#Attribution" />
- <cc:prohibits
- rdf:resource="http://creativecommons.org/ns#CommercialUse" />
- <cc:permits
- rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
- <cc:requires
- rdf:resource="http://creativecommons.org/ns#ShareAlike" />
- </cc:License>
</rdf:RDF>
</metadata>
<g
diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png
index 451273728f2..76bb67b7263 100644
--- a/release/datafiles/splash.png
+++ b/release/datafiles/splash.png
Binary files differ
diff --git a/release/datafiles/splash_2x.png b/release/datafiles/splash_2x.png
index 758178be298..c0eaba50460 100644
--- a/release/datafiles/splash_2x.png
+++ b/release/datafiles/splash_2x.png
Binary files differ
diff --git a/release/scripts/addons b/release/scripts/addons
-Subproject 74393fe915b5dadbe3066a149ef1d16575d5912
+Subproject fd695c3a81b63db072311e8516e0dbb8d447404
diff --git a/release/scripts/addons_contrib b/release/scripts/addons_contrib
-Subproject 88931a09a925a86701779a4b700508eff9fdc6b
+Subproject 8f33ffcebed445755d3453b8f486306bcf2b142
diff --git a/release/scripts/freestyle/modules/freestyle/__init__.py b/release/scripts/freestyle/modules/freestyle/__init__.py
index 5874488f684..d2795f65b6a 100644
--- a/release/scripts/freestyle/modules/freestyle/__init__.py
+++ b/release/scripts/freestyle/modules/freestyle/__init__.py
@@ -17,8 +17,21 @@
# ##### END GPL LICENSE BLOCK #####
"""
-Top-level module containing all Freestyle stylization constructs
+This module provides data types of view map components (0D and 1D
+elements), base classes for defining line stylization rules
+(predicates, functions, chaining iterators, and stroke shaders), as
+well as helper functions for style module writing.
+
+Submodules:
+
+* :mod:`freestyle.types`
+* :mod:`freestyle.predicates`
+* :mod:`freestyle.functions`
+* :mod:`freestyle.chainingiterators`
+* :mod:`freestyle.shaders`
+* :mod:`freestyle.utils`
"""
+
# module members
from . import chainingiterators, functions, predicates, shaders, types, utils
diff --git a/release/scripts/freestyle/modules/freestyle/chainingiterators.py b/release/scripts/freestyle/modules/freestyle/chainingiterators.py
index 8d144bf17fd..52f22b3e8be 100644
--- a/release/scripts/freestyle/modules/freestyle/chainingiterators.py
+++ b/release/scripts/freestyle/modules/freestyle/chainingiterators.py
@@ -17,10 +17,10 @@
# ##### END GPL LICENSE BLOCK #####
"""
-Chaining iterators used for the chaining operation to construct long
-strokes by concatenating feature edges according to selected chaining
-rules. Also intended to be a collection of examples for defining
-chaining iterators in Python
+This module contains chaining iterators used for the chaining
+operation to construct long strokes by concatenating feature edges
+according to selected chaining rules. The module is also intended to
+be a collection of examples for defining chaining iterators in Python.
"""
__all__ = (
@@ -82,12 +82,11 @@ def nature_in_preceding(nature, index):
class pyChainSilhouetteIterator(ChainingIterator):
- """Natural chaining iterator
-
- Follows the edges of the same nature following the topology of
- objects, with decreasing priority for silhouettes, then borders,
- then suggestive contours, then all other edge types. A ViewEdge
- is only chained once.
+ """
+ Natural chaining iterator that follows the edges of the same nature
+ following the topology of objects, with decreasing priority for
+ silhouettes, then borders, then suggestive contours, then all other edge
+ types. A ViewEdge is only chained once.
"""
def __init__(self, stayInSelection=True):
ChainingIterator.__init__(self, stayInSelection, True, None, True)
@@ -121,16 +120,20 @@ class pyChainSilhouetteIterator(ChainingIterator):
class pyChainSilhouetteGenericIterator(ChainingIterator):
- """Natural chaining iterator
+ """
+ Natural chaining iterator that follows the edges of the same nature
+ following the topology of objects, with decreasing priority for
+ silhouettes, then borders, then suggestive contours, then all other
+ edge types.
- Follows the edges of the same nature following the topology of
- objects, with decreasing priority for silhouettes, then borders,
- then suggestive contours, then all other edge types.
+ .. method:: __init__(self, stayInSelection=True, stayInUnvisited=True)
- :arg stayInSelection: True if it is allowed to go out of the selection
- :type stayInSelection: bool
- :arg stayInUnvisited: May the same ViewEdge be chained twice
- :type stayInUnvisited: bool
+ Builds a pyChainSilhouetteGenericIterator object.
+
+ :arg stayInSelection: True if it is allowed to go out of the selection
+ :type stayInSelection: bool
+ :arg stayInUnvisited: May the same ViewEdge be chained twice
+ :type stayInUnvisited: bool
"""
def __init__(self, stayInSelection=True, stayInUnvisited=True):
@@ -209,14 +212,18 @@ class pyExternalContourChainingIterator(ChainingIterator):
class pySketchyChainSilhouetteIterator(ChainingIterator):
- """Natural chaining iterator with a sketchy multiple touch
+ """
+ Natural chaining iterator with a sketchy multiple touch. It chains the
+ same ViewEdge multiple times to achieve a sketchy effect.
+
+ .. method:: __init__(self, nRounds=3,stayInSelection=True)
- Chains the same ViewEdge multiple times to achieve a sketchy effect.
+ Builds a pySketchyChainSilhouetteIterator object.
- :arg rounds: Number of times every Viewedge is chained.
- :type rounds: int
- :arg stayInSelection: if False, edges outside of the selection can be chained.
- :type stayInSelection: bool
+ :arg nRounds: Number of times every Viewedge is chained.
+ :type nRounds: int
+ :arg stayInSelection: if False, edges outside of the selection can be chained.
+ :type stayInSelection: bool
"""
def __init__(self, nRounds=3,stayInSelection=True):
@@ -267,10 +274,10 @@ class pySketchyChainSilhouetteIterator(ChainingIterator):
class pySketchyChainingIterator(ChainingIterator):
- """Chaining iterator designed for sketchy style
-
- It chaines the same ViewEdge several times in order to produce
- multiple strokes per ViewEdge.
+ """
+ Chaining iterator designed for sketchy style. It chaines the same
+ ViewEdge several times in order to produce multiple strokes per
+ ViewEdge.
"""
def __init__(self, nRounds=3, stayInSelection=True):
ChainingIterator.__init__(self, stayInSelection, False, None, True)
@@ -306,11 +313,16 @@ class pySketchyChainingIterator(ChainingIterator):
class pyFillOcclusionsRelativeChainingIterator(ChainingIterator):
- """Chaining iterator that fills small occlusions
+ """
+ Chaining iterator that fills small occlusions
+
+ .. method:: __init__(self, percent)
+
+ Builds a pyFillOcclusionsRelativeChainingIterator object.
- :arg percent: The maximul length of the occluded part, expressed
- in a percentage of the total chain length.
- :type percent: float
+ :arg percent: The maximul length of the occluded part, expressed
+ in a percentage of the total chain length.
+ :type percent: float
"""
def __init__(self, percent):
@@ -374,10 +386,15 @@ class pyFillOcclusionsRelativeChainingIterator(ChainingIterator):
class pyFillOcclusionsAbsoluteChainingIterator(ChainingIterator):
- """Chaining iterator that fills small occlusions
+ """
+ Chaining iterator that fills small occlusions
+
+ .. method:: __init__(self, length)
+
+ Builds a pyFillOcclusionsAbsoluteChainingIterator object.
- :arg size: The maximum length of the occluded part in pixels.
- :type size: int
+ :arg length: The maximum length of the occluded part in pixels.
+ :type length: int
"""
def __init__(self, length):
ChainingIterator.__init__(self, False, True, None, True)
@@ -429,12 +446,19 @@ class pyFillOcclusionsAbsoluteChainingIterator(ChainingIterator):
class pyFillOcclusionsAbsoluteAndRelativeChainingIterator(ChainingIterator):
- """Chaining iterator that fills small occlusions regardless of the
- selection
+ """
+ Chaining iterator that fills small occlusions regardless of the
+ selection.
+
+ .. method:: __init__(self, percent, l)
+
+ Builds a pyFillOcclusionsAbsoluteAndRelativeChainingIterator object.
- :arg percent: The maximul length of the occluded part as a
- percentage of the total chain length.
- :type percent: float
+ :arg percent: The maximul length of the occluded part as a
+ percentage of the total chain length.
+ :type percent: float
+ :arg l: Absolute length.
+ :type l: float
"""
def __init__(self, percent, l):
ChainingIterator.__init__(self, False, True, None, True)
@@ -492,12 +516,19 @@ class pyFillOcclusionsAbsoluteAndRelativeChainingIterator(ChainingIterator):
class pyFillQi0AbsoluteAndRelativeChainingIterator(ChainingIterator):
- """Chaining iterator that fills small occlusions regardless of the
- selection
+ """
+ Chaining iterator that fills small occlusions regardless of the
+ selection.
+
+ .. method:: __init__(self, percent, l)
+
+ Builds a pyFillQi0AbsoluteAndRelativeChainingIterator object.
- :arg percent: The maximul length of the occluded part as a
- percentage of the total chain length.
- :type percent: float
+ :arg percent: The maximul length of the occluded part as a
+ percentage of the total chain length.
+ :type percent: float
+ :arg l: Absolute length.
+ :type l: float
"""
def __init__(self, percent, l):
ChainingIterator.__init__(self, False, True, None, True)
@@ -554,15 +585,18 @@ class pyFillQi0AbsoluteAndRelativeChainingIterator(ChainingIterator):
class pyNoIdChainSilhouetteIterator(ChainingIterator):
- """Natural chaining iterator
+ """
+ Natural chaining iterator that follows the edges of the same nature
+ following the topology of objects, with decreasing priority for
+ silhouettes, then borders, then suggestive contours, then all other edge
+ types. It won't chain the same ViewEdge twice.
+
+ .. method:: __init__(self, stayInSelection=True)
- Follows the edges of the same nature following the topology of
- objects, with decreasing priority for silhouettes, then borders,
- then suggestive contours, then all other edge types. It won't
- chain the same ViewEdge twice.
+ Builds a pyNoIdChainSilhouetteIterator object.
- :arg stayInSelection: True if it is allowed to go out of the selection
- :type stayInSelection: bool
+ :arg stayInSelection: True if it is allowed to go out of the selection
+ :type stayInSelection: bool
"""
def __init__(self, stayInSelection=True):
diff --git a/release/scripts/freestyle/modules/freestyle/functions.py b/release/scripts/freestyle/modules/freestyle/functions.py
index 674c1f01864..48d9b2e2b39 100644
--- a/release/scripts/freestyle/modules/freestyle/functions.py
+++ b/release/scripts/freestyle/modules/freestyle/functions.py
@@ -17,11 +17,99 @@
# ##### END GPL LICENSE BLOCK #####
"""
-Functions operating on vertices (0D elements) and polylines (1D
-elements). Also intended to be a collection of examples for predicate
-definition in Python.
+This module contains functions operating on vertices (0D elements) and
+polylines (1D elements). The module is also intended to be a
+collection of examples for function definition in Python.
+
+User-defined functions inherit one of the following base classes,
+depending on the object type (0D or 1D) to operate on and the return
+value type:
+
+- :class:`freestyle.types.UnaryFunction0DDouble`
+- :class:`freestyle.types.UnaryFunction0DEdgeNature`
+- :class:`freestyle.types.UnaryFunction0DFloat`
+- :class:`freestyle.types.UnaryFunction0DId`
+- :class:`freestyle.types.UnaryFunction0DMaterial`
+- :class:`freestyle.types.UnaryFunction0DUnsigned`
+- :class:`freestyle.types.UnaryFunction0DVec2f`
+- :class:`freestyle.types.UnaryFunction0DVec3f`
+- :class:`freestyle.types.UnaryFunction0DVectorViewShape`
+- :class:`freestyle.types.UnaryFunction0DViewShape`
+- :class:`freestyle.types.UnaryFunction1DDouble`
+- :class:`freestyle.types.UnaryFunction1DEdgeNature`
+- :class:`freestyle.types.UnaryFunction1DFloat`
+- :class:`freestyle.types.UnaryFunction1DUnsigned`
+- :class:`freestyle.types.UnaryFunction1DVec2f`
+- :class:`freestyle.types.UnaryFunction1DVec3f`
+- :class:`freestyle.types.UnaryFunction1DVectorViewShape`
+- :class:`freestyle.types.UnaryFunction1DVoid`
"""
+__all__ = (
+ "ChainingTimeStampF1D",
+ "Curvature2DAngleF0D",
+ "Curvature2DAngleF1D",
+ "CurveMaterialF0D",
+ "CurveNatureF0D",
+ "CurveNatureF1D",
+ "DensityF0D",
+ "DensityF1D",
+ "GetCompleteViewMapDensityF1D",
+ "GetCurvilinearAbscissaF0D",
+ "GetDirectionalViewMapDensityF1D",
+ "GetOccludeeF0D",
+ "GetOccludeeF1D",
+ "GetOccludersF0D",
+ "GetOccludersF1D",
+ "GetParameterF0D",
+ "GetProjectedXF0D",
+ "GetProjectedXF1D",
+ "GetProjectedYF0D",
+ "GetProjectedYF1D",
+ "GetProjectedZF0D",
+ "GetProjectedZF1D",
+ "GetShapeF0D",
+ "GetShapeF1D",
+ "GetSteerableViewMapDensityF1D",
+ "GetViewMapGradientNormF0D",
+ "GetViewMapGradientNormF1D",
+ "GetXF0D",
+ "GetXF1D",
+ "GetYF0D",
+ "GetYF1D",
+ "GetZF0D",
+ "GetZF1D",
+ "IncrementChainingTimeStampF1D",
+ "LocalAverageDepthF0D",
+ "LocalAverageDepthF1D",
+ "MaterialF0D",
+ "Normal2DF0D",
+ "Normal2DF1D",
+ "Orientation2DF1D",
+ "Orientation3DF1D",
+ "QuantitativeInvisibilityF0D",
+ "QuantitativeInvisibilityF1D",
+ "ReadCompleteViewMapPixelF0D",
+ "ReadMapPixelF0D",
+ "ReadSteerableViewMapPixelF0D",
+ "ShapeIdF0D",
+ "TimeStampF1D",
+ "VertexOrientation2DF0D",
+ "VertexOrientation3DF0D",
+ "ZDiscontinuityF0D",
+ "ZDiscontinuityF1D",
+ "pyCurvilinearLengthF0D",
+ "pyDensityAnisotropyF0D",
+ "pyDensityAnisotropyF1D",
+ "pyGetInverseProjectedZF1D",
+ "pyGetSquareInverseProjectedZF1D",
+ "pyInverseCurvature2DAngleF0D",
+ "pyViewMapGradientNormF0D",
+ "pyViewMapGradientNormF1D",
+ "pyViewMapGradientVectorF0D",
+ )
+
+
# module members
from _freestyle import (
ChainingTimeStampF1D,
@@ -149,10 +237,15 @@ class pyDensityAnisotropyF0D(UnaryFunction0DDouble):
class pyViewMapGradientVectorF0D(UnaryFunction0DVec2f):
- """Returns the gradient vector for a pixel.
+ """
+ Returns the gradient vector for a pixel.
+
+ .. method:: __init__(self, level)
+
+ Builds a pyViewMapGradientVectorF0D object.
- :arg level: the level at which to compute the gradient
- :type level: int
+ :arg level: the level at which to compute the gradient
+ :type level: int
"""
def __init__(self, level):
UnaryFunction0DVec2f.__init__(self)
diff --git a/release/scripts/freestyle/modules/freestyle/predicates.py b/release/scripts/freestyle/modules/freestyle/predicates.py
index 344b89d869c..54656e450d9 100644
--- a/release/scripts/freestyle/modules/freestyle/predicates.py
+++ b/release/scripts/freestyle/modules/freestyle/predicates.py
@@ -17,11 +17,86 @@
# ##### END GPL LICENSE BLOCK #####
"""
-Predicates operating on vertices (0D elements) and polylines (1D
-elements). Also intended to be a collection of examples for predicate
-definition in Python
+This module contains predicates operating on vertices (0D elements)
+and polylines (1D elements). It is also intended to be a collection
+of examples for predicate definition in Python.
+
+User-defined predicates inherit one of the following base classes,
+depending on the object type (0D or 1D) to operate on and the arity
+(unary or binary):
+
+- :class:`freestyle.types.BinaryPredicate0D`
+- :class:`freestyle.types.BinaryPredicate1D`
+- :class:`freestyle.types.UnaryPredicate0D`
+- :class:`freestyle.types.UnaryPredicate1D`
"""
+__all__ = (
+ "AndBP1D",
+ "AndUP1D",
+ "ContourUP1D",
+ "DensityLowerThanUP1D",
+ "EqualToChainingTimeStampUP1D",
+ "EqualToTimeStampUP1D",
+ "ExternalContourUP1D",
+ "FalseBP1D",
+ "FalseUP0D",
+ "FalseUP1D",
+ "Length2DBP1D",
+ "NotBP1D",
+ "NotUP1D",
+ "ObjectNamesUP1D",
+ "OrBP1D",
+ "OrUP1D",
+ "QuantitativeInvisibilityRangeUP1D",
+ "QuantitativeInvisibilityUP1D",
+ "SameShapeIdBP1D",
+ "ShapeUP1D",
+ "TrueBP1D",
+ "TrueUP0D",
+ "TrueUP1D",
+ "ViewMapGradientNormBP1D",
+ "WithinImageBoundaryUP1D",
+ "pyBackTVertexUP0D",
+ "pyClosedCurveUP1D",
+ "pyDensityFunctorUP1D",
+ "pyDensityUP1D",
+ "pyDensityVariableSigmaUP1D",
+ "pyHighDensityAnisotropyUP1D",
+ "pyHighDirectionalViewMapDensityUP1D",
+ "pyHighSteerableViewMapDensityUP1D",
+ "pyHighViewMapDensityUP1D",
+ "pyHighViewMapGradientNormUP1D",
+ "pyHigherCurvature2DAngleUP0D",
+ "pyHigherLengthUP1D",
+ "pyHigherNumberOfTurnsUP1D",
+ "pyIsInOccludersListUP1D",
+ "pyIsOccludedByIdListUP1D",
+ "pyIsOccludedByItselfUP1D",
+ "pyIsOccludedByUP1D",
+ "pyLengthBP1D",
+ "pyLowDirectionalViewMapDensityUP1D",
+ "pyLowSteerableViewMapDensityUP1D",
+ "pyNFirstUP1D",
+ "pyNatureBP1D",
+ "pyNatureUP1D",
+ "pyParameterUP0D",
+ "pyParameterUP0DGoodOne",
+ "pyProjectedXBP1D",
+ "pyProjectedYBP1D",
+ "pyShapeIdListUP1D",
+ "pyShapeIdUP1D",
+ "pyShuffleBP1D",
+ "pySilhouetteFirstBP1D",
+ "pyUEqualsUP0D",
+ "pyVertexNatureUP0D",
+ "pyViewMapGradientNormBP1D",
+ "pyZBP1D",
+ "pyZDiscontinuityBP1D",
+ "pyZSmallerUP1D",
+ )
+
+
# module members
from _freestyle import (
ContourUP1D,
@@ -62,6 +137,8 @@ from freestyle.functions import (
GetCurvilinearAbscissaF0D,
GetDirectionalViewMapDensityF1D,
GetOccludersF1D,
+ GetProjectedXF1D,
+ GetProjectedYF1D,
GetProjectedZF1D,
GetShapeF1D,
GetSteerableViewMapDensityF1D,
@@ -511,7 +588,7 @@ class NotBP1D(BinaryPredicate1D):
self._predicate = predicate
def __call__(self, i1, i2):
- return (not self._precicate(i1, i2))
+ return (not self._predicate(i1, i2))
class pyZBP1D(BinaryPredicate1D):
@@ -523,6 +600,24 @@ class pyZBP1D(BinaryPredicate1D):
return (self.func(i1) > self.func(i2))
+class pyProjectedXBP1D(BinaryPredicate1D):
+ def __init__(self, iType=IntegrationType.MEAN):
+ BinaryPredicate1D.__init__(self)
+ self.func = GetProjectedXF1D(iType)
+
+ def __call__(self, i1, i2):
+ return (self.func(i1) > self.func(i2))
+
+
+class pyProjectedYBP1D(BinaryPredicate1D):
+ def __init__(self, iType=IntegrationType.MEAN):
+ BinaryPredicate1D.__init__(self)
+ self.func = GetProjectedYF1D(iType)
+
+ def __call__(self, i1, i2):
+ return (self.func(i1) > self.func(i2))
+
+
class pyZDiscontinuityBP1D(BinaryPredicate1D):
def __init__(self, iType=IntegrationType.MEAN):
BinaryPredicate1D.__init__(self)
diff --git a/release/scripts/freestyle/modules/freestyle/shaders.py b/release/scripts/freestyle/modules/freestyle/shaders.py
index 502d9b69a97..508df7feca0 100644
--- a/release/scripts/freestyle/modules/freestyle/shaders.py
+++ b/release/scripts/freestyle/modules/freestyle/shaders.py
@@ -22,10 +22,80 @@
# Purpose : Stroke shaders to be used for creation of stylized strokes
"""
-Stroke shaders used for creation of stylized strokes. Also intended
-to be a collection of examples for shader definition in Python.
+This module contains stroke shaders used for creation of stylized
+strokes. It is also intended to be a collection of examples for
+shader definition in Python.
+
+User-defined stroke shaders inherit the
+:class:`freestyle.types.StrokeShader` class.
"""
+__all__ = (
+ "BackboneStretcherShader",
+ "BezierCurveShader",
+ "BlenderTextureShader",
+ "CalligraphicShader",
+ "ColorNoiseShader",
+ "ColorVariationPatternShader",
+ "ConstantColorShader",
+ "ConstantThicknessShader",
+ "ConstrainedIncreasingThicknessShader",
+ "GuidingLinesShader",
+ "IncreasingColorShader",
+ "IncreasingThicknessShader",
+ "PolygonalizationShader",
+ "RoundCapShader",
+ "SamplingShader",
+ "SmoothingShader",
+ "SpatialNoiseShader",
+ "SquareCapShader",
+ "StrokeTextureShader",
+ "StrokeTextureStepShader",
+ "TextureAssignerShader",
+ "ThicknessNoiseShader",
+ "ThicknessVariationPatternShader",
+ "TipRemoverShader",
+ "fstreamShader",
+ "py2DCurvatureColorShader",
+ "pyBackboneStretcherNoCuspShader",
+ "pyBackboneStretcherShader",
+ "pyBluePrintCirclesShader",
+ "pyBluePrintDirectedSquaresShader",
+ "pyBluePrintEllipsesShader",
+ "pyBluePrintSquaresShader",
+ "pyConstantColorShader",
+ "pyConstantThicknessShader",
+ "pyConstrainedIncreasingThicknessShader",
+ "pyDecreasingThicknessShader",
+ "pyDepthDiscontinuityThicknessShader",
+ "pyDiffusion2Shader",
+ "pyFXSVaryingThicknessWithDensityShader",
+ "pyGuidingLineShader",
+ "pyHLRShader",
+ "pyImportance2DThicknessShader",
+ "pyImportance3DThicknessShader",
+ "pyIncreasingColorShader",
+ "pyIncreasingThicknessShader",
+ "pyInterpolateColorShader",
+ "pyLengthDependingBackboneStretcherShader",
+ "pyMaterialColorShader",
+ "pyModulateAlphaShader",
+ "pyNonLinearVaryingThicknessShader",
+ "pyPerlinNoise1DShader",
+ "pyPerlinNoise2DShader",
+ "pyRandomColorShader",
+ "pySLERPThicknessShader",
+ "pySamplingShader",
+ "pySinusDisplacementShader",
+ "pyTVertexRemoverShader",
+ "pyTVertexThickenerShader",
+ "pyTimeColorShader",
+ "pyTipRemoverShader",
+ "pyZDependingThicknessShader",
+ "streamShader",
+ )
+
+
# module members
from _freestyle import (
BackboneStretcherShader,
@@ -671,10 +741,8 @@ class pyTipRemoverShader(StrokeShader):
@staticmethod
def check_vertex(v, length):
- """
- Returns True if the given strokevertex is less than self._l away
- from the stroke's tip and therefore should be removed.
- """
+ # Returns True if the given strokevertex is less than self._l away
+ # from the stroke's tip and therefore should be removed.
return (v.curvilinear_abscissa < length or v.stroke_length-v.curvilinear_abscissa < length)
def shade(self, stroke):
diff --git a/release/scripts/freestyle/modules/freestyle/types.py b/release/scripts/freestyle/modules/freestyle/types.py
index 8f596fd275c..22f80f41dfc 100644
--- a/release/scripts/freestyle/modules/freestyle/types.py
+++ b/release/scripts/freestyle/modules/freestyle/types.py
@@ -17,9 +17,96 @@
# ##### END GPL LICENSE BLOCK #####
"""
-Submodule containing all Freestyle types.
+This module contains core classes of the Freestyle Python API,
+including data types of view map components (0D and 1D elements), base
+classes for user-defined line stylization rules (predicates,
+functions, chaining iterators, and stroke shaders), and operators.
+
+Class hierarchy:
+
+- :class:`BBox`
+- :class:`BinaryPredicate0D`
+- :class:`BinaryPredicate1D`
+- :class:`Id`
+- :class:`Interface0D`
+
+ - :class:`CurvePoint`
+
+ - :class:`StrokeVertex`
+
+ - :class:`SVertex`
+ - :class:`ViewVertex`
+
+ - :class:`NonTVertex`
+ - :class:`TVertex`
+
+- :class:`Interface1D`
+
+ - :class:`Curve`
+
+ - :class:`Chain`
+
+ - :class:`FEdge`
+
+ - :class:`FEdgeSharp`
+ - :class:`FEdgeSmooth`
+
+ - :class:`Stroke`
+ - :class:`ViewEdge`
+
+- :class:`Iterator`
+
+ - :class:`AdjacencyIterator`
+ - :class:`CurvePointIterator`
+ - :class:`Interface0DIterator`
+ - :class:`SVertexIterator`
+ - :class:`StrokeVertexIterator`
+ - :class:`ViewEdgeIterator`
+
+ - :class:`ChainingIterator`
+
+ - :class:`orientedViewEdgeIterator`
+
+- :class:`Material`
+- :class:`Noise`
+- :class:`Operators`
+- :class:`SShape`
+- :class:`StrokeAttribute`
+- :class:`StrokeShader`
+- :class:`UnaryFunction0D`
+
+ - :class:`UnaryFunction0DDouble`
+ - :class:`UnaryFunction0DEdgeNature`
+ - :class:`UnaryFunction0DFloat`
+ - :class:`UnaryFunction0DId`
+ - :class:`UnaryFunction0DMaterial`
+ - :class:`UnaryFunction0DUnsigned`
+ - :class:`UnaryFunction0DVec2f`
+ - :class:`UnaryFunction0DVec3f`
+ - :class:`UnaryFunction0DVectorViewShape`
+ - :class:`UnaryFunction0DViewShape`
+
+- :class:`UnaryFunction1D`
+
+ - :class:`UnaryFunction1DDouble`
+ - :class:`UnaryFunction1DEdgeNature`
+ - :class:`UnaryFunction1DFloat`
+ - :class:`UnaryFunction1DUnsigned`
+ - :class:`UnaryFunction1DVec2f`
+ - :class:`UnaryFunction1DVec3f`
+ - :class:`UnaryFunction1DVectorViewShape`
+ - :class:`UnaryFunction1DVoid`
+
+- :class:`UnaryPredicate0D`
+- :class:`UnaryPredicate1D`
+- :class:`ViewMap`
+- :class:`ViewShape`
+- :class:`IntegrationType`
+- :class:`MediumType`
+- :class:`Nature`
"""
+
# module members
from _freestyle import (
AdjacencyIterator,
diff --git a/release/scripts/freestyle/modules/freestyle/utils.py b/release/scripts/freestyle/modules/freestyle/utils.py
index e6dca93b777..e0679a53954 100644
--- a/release/scripts/freestyle/modules/freestyle/utils.py
+++ b/release/scripts/freestyle/modules/freestyle/utils.py
@@ -17,9 +17,33 @@
# ##### END GPL LICENSE BLOCK #####
"""
-Helper functions used for Freestyle style module writing.
+This module contains helper functions used for Freestyle style module
+writing.
"""
+__all__ = (
+ "ContextFunctions",
+ "bound",
+ "bounding_box",
+ "find_matching_vertex",
+ "getCurrentScene",
+ "get_chain_length",
+ "get_test_stroke",
+ "integrate",
+ "iter_distance_along_stroke",
+ "iter_distance_from_camera",
+ "iter_distance_from_object",
+ "iter_material_value",
+ "iter_t2d_along_stroke",
+ "pairwise",
+ "phase_to_direction",
+ "rgb_to_bw",
+ "stroke_curvature",
+ "stroke_normal",
+ "tripplewise",
+ )
+
+
# module members
from _freestyle import (
ContextFunctions,
@@ -27,13 +51,13 @@ from _freestyle import (
integrate,
)
+# constructs for helper functions in Python
from freestyle.types import (
Interface0DIterator,
Stroke,
StrokeVertexIterator,
)
-
from mathutils import Vector
from functools import lru_cache, namedtuple
from math import cos, sin, pi
diff --git a/release/scripts/freestyle/modules/parameter_editor.py b/release/scripts/freestyle/modules/parameter_editor.py
index ebd09bd0181..9ac5c665f1e 100644
--- a/release/scripts/freestyle/modules/parameter_editor.py
+++ b/release/scripts/freestyle/modules/parameter_editor.py
@@ -62,7 +62,10 @@ from freestyle.predicates import (
TrueBP1D,
TrueUP1D,
WithinImageBoundaryUP1D,
+ pyNFirstUP1D,
pyNatureUP1D,
+ pyProjectedXBP1D,
+ pyProjectedYBP1D,
pyZBP1D,
)
from freestyle.shaders import (
@@ -1006,11 +1009,6 @@ def process(layer_name, lineset_name):
Operators.sequential_split(SplitPatternStartingUP0D(controller),
SplitPatternStoppingUP0D(controller),
sampling)
- # select chains
- if linestyle.use_length_min or linestyle.use_length_max:
- length_min = linestyle.length_min if linestyle.use_length_min else None
- length_max = linestyle.length_max if linestyle.use_length_max else None
- Operators.select(LengthThresholdUP1D(length_min, length_max))
# sort selected chains
if linestyle.use_sorting:
integration = integration_types.get(linestyle.integration_type, IntegrationType.MEAN)
@@ -1018,9 +1016,20 @@ def process(layer_name, lineset_name):
bpred = pyZBP1D(integration)
elif linestyle.sort_key == '2D_LENGTH':
bpred = Length2DBP1D()
+ elif linestyle.sort_key == 'PROJECTED_X':
+ bpred = pyProjectedXBP1D(integration)
+ elif linestyle.sort_key == 'PROJECTED_Y':
+ bpred = pyProjectedYBP1D(integration)
if linestyle.sort_order == 'REVERSE':
bpred = NotBP1D(bpred)
Operators.sort(bpred)
+ # select chains
+ if linestyle.use_length_min or linestyle.use_length_max:
+ length_min = linestyle.length_min if linestyle.use_length_min else None
+ length_max = linestyle.length_max if linestyle.use_length_max else None
+ Operators.select(LengthThresholdUP1D(length_min, length_max))
+ if linestyle.use_chain_count:
+ Operators.select(pyNFirstUP1D(linestyle.chain_count))
# prepare a list of stroke shaders
shaders_list = []
for m in linestyle.geometry_modifiers:
diff --git a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
index ad2a70b84e8..8874ecceb77 100644
--- a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
+++ b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py
@@ -343,10 +343,10 @@ def dump_rna_messages(msgs, reports, settings, verbose=False):
process_msg(msgs, default_context, cls.__doc__, msgsrc, reports, check_ctxt_rna_tip, settings)
# Panels' "tabs" system.
- if hasattr(bl_rna, 'bl_category') and bl_rna.bl_category:
+ if hasattr(bl_rna, 'bl_category') and bl_rna.bl_category:
process_msg(msgs, default_context, bl_rna.bl_category, msgsrc, reports, check_ctxt_rna, settings)
- if hasattr(bl_rna, 'bl_label') and bl_rna.bl_label:
+ if hasattr(bl_rna, 'bl_label') and bl_rna.bl_label:
process_msg(msgs, msgctxt, bl_rna.bl_label, msgsrc, reports, check_ctxt_rna, settings)
walk_properties(cls)
diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py
index 85977642bbb..911e1764698 100644
--- a/release/scripts/modules/bl_i18n_utils/utils.py
+++ b/release/scripts/modules/bl_i18n_utils/utils.py
@@ -1343,7 +1343,7 @@ class I18n:
#key = self.settings.PO_HEADER_KEY
#for uid, trans in self.trans.items():
#if key not in trans.msgs:
- #trans.msgs[key]
+ #trans.msgs[key]
self.unescape()
def write(self, kind, langs=set()):
diff --git a/release/scripts/modules/bpy_extras/view3d_utils.py b/release/scripts/modules/bpy_extras/view3d_utils.py
index ad555a417d7..b25024fca9b 100644
--- a/release/scripts/modules/bpy_extras/view3d_utils.py
+++ b/release/scripts/modules/bpy_extras/view3d_utils.py
@@ -54,9 +54,13 @@ def region_2d_to_vector_3d(region, rv3d, coord):
w = out.dot(persinv[3].xyz) + persinv[3][3]
- return ((persinv * out) / w) - viewinv.translation
+ view_vector = ((persinv * out) / w) - viewinv.translation
else:
- return viewinv.col[2].xyz.normalized()
+ view_vector = -viewinv.col[2].xyz
+
+ view_vector.normalize()
+
+ return view_vector
def region_2d_to_origin_3d(region, rv3d, coord):
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index bc2e9368b71..e19766310ec 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -694,7 +694,7 @@ class _GenericUI:
draw_funcs = cls._dyn_ui_initialize()
try:
draw_funcs.remove(draw_func)
- except:
+ except ValueError:
pass
diff --git a/release/scripts/modules/console/complete_namespace.py b/release/scripts/modules/console/complete_namespace.py
index 74406d5e002..992bb72aa08 100644
--- a/release/scripts/modules/console/complete_namespace.py
+++ b/release/scripts/modules/console/complete_namespace.py
@@ -186,7 +186,7 @@ def complete(word, namespace, private=True):
except Exception:
return []
# ignore basic types
- if type(obj) in (bool, float, int, str):
+ if type(obj) in {bool, float, int, str}:
return []
# an extra char '[', '(' or '.' will be added
if hasattr(obj, '__getitem__') and not is_struct_seq(obj):
diff --git a/release/scripts/modules/rna_xml.py b/release/scripts/modules/rna_xml.py
index 9776993b74b..41f890de51f 100644
--- a/release/scripts/modules/rna_xml.py
+++ b/release/scripts/modules/rna_xml.py
@@ -92,7 +92,6 @@ def rna2xml(fw=print_ln,
bpy.types.Sequence,
)
-
def number_to_str(val, val_type):
if val_type == int:
return "%d" % val
@@ -245,13 +244,13 @@ def xml2rna(root_xml,
):
def rna2xml_node(xml_node, value):
-# print("evaluating:", xml_node.nodeName)
+ # print("evaluating:", xml_node.nodeName)
# ---------------------------------------------------------------------
# Simple attributes
for attr in xml_node.attributes.keys():
-# print(" ", attr)
+ # print(" ", attr)
subvalue = getattr(value, attr, Ellipsis)
if subvalue is Ellipsis:
diff --git a/release/scripts/presets/interface_theme/back_to_black.xml b/release/scripts/presets/interface_theme/back_to_black.xml
index 152e944a7ba..0d377f9af68 100644
--- a/release/scripts/presets/interface_theme/back_to_black.xml
+++ b/release/scripts/presets/interface_theme/back_to_black.xml
@@ -156,7 +156,7 @@
<ThemeWidgetColors outline="#0a0a0a"
inner="#191919e6"
inner_sel="#8c8c8cff"
- item="#2d2d2de6"
+ item="#33406be6"
text="#a0a0a0"
text_sel="#ffffff"
show_shaded="TRUE"
@@ -286,6 +286,7 @@
editmesh_active="#ff020080"
normal="#22dddd"
vertex_normal="#2361dd"
+ split_normal="#dd23dd"
bone_solid="#c8c8c8"
bone_pose="#50c8ff"
bone_pose_active="#8cffff"
@@ -310,7 +311,7 @@
tab_active="#212947"
tab_inactive="#000000"
tab_back="#060606ff"
- tab_outline="#3a3a3a">
+ tab_outline="#000000">
<gradients>
<ThemeGradientColors show_grad="TRUE"
gradient="#0a0a0a"
diff --git a/release/scripts/presets/interface_theme/blender_24x.xml b/release/scripts/presets/interface_theme/blender_24x.xml
index 9cb3276b103..ef452aff353 100644
--- a/release/scripts/presets/interface_theme/blender_24x.xml
+++ b/release/scripts/presets/interface_theme/blender_24x.xml
@@ -153,11 +153,11 @@
</ThemeWidgetColors>
</wcol_menu_back>
<wcol_pie_menu>
- <ThemeWidgetColors outline="#0a0a0a"
- inner="#191919e6"
- inner_sel="#8c8c8cff"
- item="#2d2d2de6"
- text="#a0a0a0"
+ <ThemeWidgetColors outline="#262626"
+ inner="#b4b4b42e"
+ inner_sel="#646464b4"
+ item="#b4b4b4ff"
+ text="#000000"
text_sel="#ffffff"
show_shaded="TRUE"
shadetop="10"
@@ -237,7 +237,7 @@
</ThemeUserInterface>
</user_interface>
<view_3d>
- <ThemeView3D grid="#5c5c5c"
+ <ThemeView3D grid="#4c4c4c"
wire="#000000"
wire_edit="#000000"
lamp="#00000028"
@@ -245,23 +245,23 @@
camera="#000000"
view_overlay="#000000"
empty="#000000"
- object_selected="#ff88ff"
- object_active="#ffbbff"
- object_grouped="#104010"
+ object_selected="#f15800"
+ object_active="#ffaa40"
+ object_grouped="#083008"
object_grouped_active="#55bb55"
transform="#ffffff"
- vertex="#ff70ff"
- vertex_select="#ffff70"
- vertex_size="2"
+ vertex="#000000"
+ vertex_select="#ff8500"
+ vertex_size="3"
vertex_unreferenced="#000000"
- edge_select="#cece38"
- edge_seam="#e69632"
- edge_sharp="#ff2020"
+ edge_select="#ffa000"
+ edge_seam="#db2512"
+ edge_sharp="#00abc0"
edge_crease="#cc0099"
edge_facesel="#4b4b4b"
freestyle_edge_mark="#7fff7f"
- face="#0032961e"
- face_select="#c864c83c"
+ face="#00000000"
+ face_select="#ff85003c"
face_dot="#ff8a30"
facedot_size="4"
freestyle_face_mark="#7fff7f33"
@@ -286,6 +286,7 @@
editmesh_active="#ffffff80"
normal="#22dddd"
vertex_normal="#2361dd"
+ split_normal="#dd23dd"
bone_solid="#c8c8c8"
bone_pose="#50c8ff"
bone_pose_active="#8cffff"
@@ -293,7 +294,7 @@
outline_width="1"
bundle_solid="#c8c8c8"
camera_path="#000000"
- skin_root="#000000"
+ skin_root="#b44d4d"
paint_curve_handle="#7fff7f7f"
paint_curve_pivot="#ff7f7f7f">
<space>
@@ -314,7 +315,7 @@
<gradients>
<ThemeGradientColors show_grad="FALSE"
gradient="#000000"
- high_gradient="#757575">
+ high_gradient="#7e7e7e">
</ThemeGradientColors>
</gradients>
<panelcolors>
@@ -749,8 +750,8 @@
wire_select="#ffffff"
selected_text="#7f7070"
node_backdrop="#9b9b9ba0"
- converter_node="#686a75"
- color_node="#6c696f"
+ converter_node="#c6bfbf"
+ color_node="#457b95"
group_node="#69756e"
group_socket_node="#dfca35"
frame_node="#9a9b9ba0"
@@ -760,12 +761,12 @@
input_node="#646464"
output_node="#646464"
filter_node="#6c696f"
- vector_node="#6c696f"
- texture_node="#6c696f"
- shader_node="#6c696f"
+ vector_node="#6f578c"
+ texture_node="#8395bf"
+ shader_node="#4f9370"
script_node="#6c696f"
pattern_node="#6c696f"
- layout_node="#6c696f">
+ layout_node="#6e6f69">
<space>
<ThemeSpaceGeneric back="#757575"
title="#000000"
@@ -983,7 +984,7 @@
handle_sel_auto_clamped="#000000"
handle_vertex="#000000"
handle_vertex_select="#ffff00"
- handle_vertex_size="4">
+ handle_vertex_size="5">
<space>
<ThemeSpaceGeneric back="#757575"
title="#000000"
diff --git a/release/scripts/presets/interface_theme/elsyiun.xml b/release/scripts/presets/interface_theme/elsyiun.xml
index 2d213d0ed70..9b9804b5511 100644
--- a/release/scripts/presets/interface_theme/elsyiun.xml
+++ b/release/scripts/presets/interface_theme/elsyiun.xml
@@ -154,9 +154,9 @@
</wcol_menu_back>
<wcol_pie_menu>
<ThemeWidgetColors outline="#0a0a0a"
- inner="#191919e6"
+ inner="#414141e6"
inner_sel="#8c8c8cff"
- item="#2d2d2de6"
+ item="#b67e3ee6"
text="#a0a0a0"
text_sel="#ffffff"
show_shaded="TRUE"
@@ -286,6 +286,7 @@
editmesh_active="#ffffff80"
normal="#22dddd"
vertex_normal="#2361dd"
+ split_normal="#dd23dd"
bone_solid="#c8c8c8"
bone_pose="#50c8ff"
bone_pose_active="#8cffff"
@@ -305,9 +306,9 @@
header_text_hi="#ffffff"
button="#3b3b3b57"
button_title="#979797"
- button_text="#979797"
+ button_text="#c5c5c5"
button_text_hi="#ffffff"
- tab_active="#464646"
+ tab_active="#b67e3e"
tab_inactive="#393939"
tab_back="#404040ff"
tab_outline="#323232">
diff --git a/release/scripts/presets/interface_theme/hexagon.xml b/release/scripts/presets/interface_theme/hexagon.xml
index d2221bc9935..6f24d989e79 100644
--- a/release/scripts/presets/interface_theme/hexagon.xml
+++ b/release/scripts/presets/interface_theme/hexagon.xml
@@ -154,11 +154,11 @@
</wcol_menu_back>
<wcol_pie_menu>
<ThemeWidgetColors outline="#0a0a0a"
- inner="#191919e6"
+ inner="#5a5e6ae6"
inner_sel="#8c8c8cff"
- item="#2d2d2de6"
- text="#a0a0a0"
- text_sel="#ffffff"
+ item="#8f92a1e6"
+ text="#d6d6d6"
+ text_sel="#000000"
show_shaded="TRUE"
shadetop="10"
shadedown="-10">
@@ -286,6 +286,7 @@
editmesh_active="#00e8ff80"
normal="#00ffff"
vertex_normal="#2361dd"
+ split_normal="#dd23dd"
bone_solid="#c8c8c8"
bone_pose="#50c8ff"
bone_pose_active="#8cffff"
diff --git a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
index 06d29a97745..e702e25bc86 100644
--- a/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
+++ b/release/scripts/presets/interface_theme/ubuntu_ambiance.xml
@@ -156,7 +156,7 @@
<ThemeWidgetColors outline="#0a0a0a"
inner="#191919e6"
inner_sel="#8c8c8cff"
- item="#2d2d2de6"
+ item="#6a3859e6"
text="#a0a0a0"
text_sel="#ffffff"
show_shaded="TRUE"
@@ -286,6 +286,7 @@
editmesh_active="#ffffff80"
normal="#19b6ee"
vertex_normal="#19b6ee"
+ split_normal="#dd23dd"
bone_solid="#c8c8c8"
bone_pose="#50c8ff"
bone_pose_active="#8cffff"
diff --git a/release/scripts/startup/bl_operators/__init__.py b/release/scripts/startup/bl_operators/__init__.py
index 4f6863a590c..e44fce63acd 100644
--- a/release/scripts/startup/bl_operators/__init__.py
+++ b/release/scripts/startup/bl_operators/__init__.py
@@ -9,7 +9,7 @@
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
-#,
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
diff --git a/release/scripts/startup/bl_operators/anim.py b/release/scripts/startup/bl_operators/anim.py
index 42ab99ed399..756b75b8d03 100644
--- a/release/scripts/startup/bl_operators/anim.py
+++ b/release/scripts/startup/bl_operators/anim.py
@@ -306,7 +306,8 @@ class UpdateAnimatedTransformConstraint(Operator):
paths = from_paths | to_paths
def update_cb(base, class_name, old_path, fcurve, options):
- print(options)
+ # print(options)
+
def handle_deg2rad(fcurve):
if fcurve is not None:
if hasattr(fcurve, "keyframes"):
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py
index 0508c32ca03..4ce300ecce2 100644
--- a/release/scripts/startup/bl_operators/clip.py
+++ b/release/scripts/startup/bl_operators/clip.py
@@ -780,9 +780,9 @@ class CLIP_OT_setup_tracking_scene(Operator):
def _getPlaneVertices(half_size, z):
return [(-half_size, -half_size, z),
- (-half_size, half_size, z),
+ (half_size, -half_size, z),
(half_size, half_size, z),
- (half_size, -half_size, z)]
+ (-half_size, half_size, z)]
def _createGround(self, scene):
vertices = self._getPlaneVertices(4.0, 0.0)
diff --git a/release/scripts/startup/bl_operators/object_quick_effects.py b/release/scripts/startup/bl_operators/object_quick_effects.py
index 32688299b76..06dc82d2b77 100644
--- a/release/scripts/startup/bl_operators/object_quick_effects.py
+++ b/release/scripts/startup/bl_operators/object_quick_effects.py
@@ -289,8 +289,8 @@ def obj_bb_minmax(obj, min_co, max_co):
max_co[0] = max(bb_vec[0], max_co[0])
max_co[1] = max(bb_vec[1], max_co[1])
max_co[2] = max(bb_vec[2], max_co[2])
-
-
+
+
def grid_location(x, y):
return (x * 200, y * 150)
@@ -387,94 +387,96 @@ class QuickSmoke(Operator):
links.new(node_add_shader_1.outputs["Shader"],
node_out.inputs["Volume"])
- # Smoke
-
- # Add shader 2
- node_add_shader_2 = nodes.new(type='ShaderNodeAddShader')
- node_add_shader_2.location = grid_location(4, 2)
- links.new(node_add_shader_2.outputs["Shader"],
- node_add_shader_1.inputs[0])
-
- # Volume scatter
- node_scatter = nodes.new(type='ShaderNodeVolumeScatter')
- node_scatter.location = grid_location(3, 3)
- links.new(node_scatter.outputs["Volume"],
- node_add_shader_2.inputs[0])
-
- # Volume absorption
- node_absorption = nodes.new(type='ShaderNodeVolumeAbsorption')
- node_absorption.location = grid_location(3, 2)
- links.new(node_absorption.outputs["Volume"],
- node_add_shader_2.inputs[1])
-
- # Density Multiplier
- node_densmult = nodes.new(type='ShaderNodeMath')
- node_densmult.location = grid_location(2, 2)
- node_densmult.operation = 'MULTIPLY'
- node_densmult.inputs[1].default_value = 5.0
- links.new(node_densmult.outputs["Value"],
- node_scatter.inputs["Density"])
- links.new(node_densmult.outputs["Value"],
- node_absorption.inputs["Density"])
-
- # Attribute "density"
- node_attrib_density = nodes.new(type='ShaderNodeAttribute')
- node_attrib_density.attribute_name = "density"
- node_attrib_density.location = grid_location(1, 2)
- links.new(node_attrib_density.outputs["Fac"],
- node_densmult.inputs[0])
-
- # Attribute "color"
- node_attrib_color = nodes.new(type='ShaderNodeAttribute')
- node_attrib_color.attribute_name = "color"
- node_attrib_color.location = grid_location(2, 3)
- links.new(node_attrib_color.outputs["Color"],
- node_scatter.inputs["Color"])
- links.new(node_attrib_color.outputs["Color"],
- node_absorption.inputs["Color"])
-
- # Fire
-
- # Emission
- node_emission = nodes.new(type='ShaderNodeEmission')
- node_emission.inputs["Color"].default_value = (0.8, 0.1, 0.01, 1.0)
- node_emission.location = grid_location(4, 1)
- links.new(node_emission.outputs["Emission"],
- node_add_shader_1.inputs[1])
-
- # Flame strength multiplier
- node_flame_strength_mult = nodes.new(type='ShaderNodeMath')
- node_flame_strength_mult.location = grid_location(3, 1)
- node_flame_strength_mult.operation = 'MULTIPLY'
- node_flame_strength_mult.inputs[1].default_value = 2.5
- links.new(node_flame_strength_mult.outputs["Value"],
- node_emission.inputs["Strength"])
-
- # Color ramp Flame
- node_flame_ramp = nodes.new(type='ShaderNodeValToRGB')
- node_flame_ramp.location = grid_location(1, 1)
- ramp = node_flame_ramp.color_ramp
- ramp.interpolation = 'EASE'
-
- # orange
- elem = ramp.elements.new(0.5)
- elem.color = (1.0, 0.128, 0.0, 1.0)
-
- # yellow
- elem = ramp.elements.new(0.9)
- elem.color = (0.9, 0.6, 0.1, 1.0)
-
- links.new(node_flame_ramp.outputs["Color"],
- node_emission.inputs["Color"])
-
- # Attribute "flame"
- node_attrib_flame = nodes.new(type='ShaderNodeAttribute')
- node_attrib_flame.attribute_name = "flame"
- node_attrib_flame.location = grid_location(0, 1)
- links.new(node_attrib_flame.outputs["Fac"],
- node_flame_ramp.inputs["Fac"])
- links.new(node_attrib_flame.outputs["Fac"],
- node_flame_strength_mult.inputs[0])
+ if self.style in {'SMOKE', 'BOTH'}:
+ # Smoke
+
+ # Add shader 2
+ node_add_shader_2 = nodes.new(type='ShaderNodeAddShader')
+ node_add_shader_2.location = grid_location(4, 2)
+ links.new(node_add_shader_2.outputs["Shader"],
+ node_add_shader_1.inputs[0])
+
+ # Volume scatter
+ node_scatter = nodes.new(type='ShaderNodeVolumeScatter')
+ node_scatter.location = grid_location(3, 3)
+ links.new(node_scatter.outputs["Volume"],
+ node_add_shader_2.inputs[0])
+
+ # Volume absorption
+ node_absorption = nodes.new(type='ShaderNodeVolumeAbsorption')
+ node_absorption.location = grid_location(3, 2)
+ links.new(node_absorption.outputs["Volume"],
+ node_add_shader_2.inputs[1])
+
+ # Density Multiplier
+ node_densmult = nodes.new(type='ShaderNodeMath')
+ node_densmult.location = grid_location(2, 2)
+ node_densmult.operation = 'MULTIPLY'
+ node_densmult.inputs[1].default_value = 5.0
+ links.new(node_densmult.outputs["Value"],
+ node_scatter.inputs["Density"])
+ links.new(node_densmult.outputs["Value"],
+ node_absorption.inputs["Density"])
+
+ # Attribute "density"
+ node_attrib_density = nodes.new(type='ShaderNodeAttribute')
+ node_attrib_density.attribute_name = "density"
+ node_attrib_density.location = grid_location(1, 2)
+ links.new(node_attrib_density.outputs["Fac"],
+ node_densmult.inputs[0])
+
+ # Attribute "color"
+ node_attrib_color = nodes.new(type='ShaderNodeAttribute')
+ node_attrib_color.attribute_name = "color"
+ node_attrib_color.location = grid_location(2, 3)
+ links.new(node_attrib_color.outputs["Color"],
+ node_scatter.inputs["Color"])
+ links.new(node_attrib_color.outputs["Color"],
+ node_absorption.inputs["Color"])
+
+ if self.style in {'FIRE', 'BOTH'}:
+ # Fire
+
+ # Emission
+ node_emission = nodes.new(type='ShaderNodeEmission')
+ node_emission.inputs["Color"].default_value = (0.8, 0.1, 0.01, 1.0)
+ node_emission.location = grid_location(4, 1)
+ links.new(node_emission.outputs["Emission"],
+ node_add_shader_1.inputs[1])
+
+ # Flame strength multiplier
+ node_flame_strength_mult = nodes.new(type='ShaderNodeMath')
+ node_flame_strength_mult.location = grid_location(3, 1)
+ node_flame_strength_mult.operation = 'MULTIPLY'
+ node_flame_strength_mult.inputs[1].default_value = 2.5
+ links.new(node_flame_strength_mult.outputs["Value"],
+ node_emission.inputs["Strength"])
+
+ # Color ramp Flame
+ node_flame_ramp = nodes.new(type='ShaderNodeValToRGB')
+ node_flame_ramp.location = grid_location(1, 1)
+ ramp = node_flame_ramp.color_ramp
+ ramp.interpolation = 'EASE'
+
+ # orange
+ elem = ramp.elements.new(0.5)
+ elem.color = (1.0, 0.128, 0.0, 1.0)
+
+ # yellow
+ elem = ramp.elements.new(0.9)
+ elem.color = (0.9, 0.6, 0.1, 1.0)
+
+ links.new(node_flame_ramp.outputs["Color"],
+ node_emission.inputs["Color"])
+
+ # Attribute "flame"
+ node_attrib_flame = nodes.new(type='ShaderNodeAttribute')
+ node_attrib_flame.attribute_name = "flame"
+ node_attrib_flame.location = grid_location(0, 1)
+ links.new(node_attrib_flame.outputs["Fac"],
+ node_flame_ramp.inputs["Fac"])
+ links.new(node_attrib_flame.outputs["Fac"],
+ node_flame_strength_mult.inputs[0])
# Blender Internal
else:
diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py
index 5c3f94a8739..8d04cb132e6 100644
--- a/release/scripts/startup/bl_operators/wm.py
+++ b/release/scripts/startup/bl_operators/wm.py
@@ -1934,7 +1934,6 @@ class WM_OT_addon_install(Operator):
try:
os.makedirs(path_addons, exist_ok=True)
except:
- import traceback
traceback.print_exc()
# Check if we are installing from a target path,
diff --git a/release/scripts/startup/bl_ui/properties_freestyle.py b/release/scripts/startup/bl_ui/properties_freestyle.py
index 58818e90440..6abd6f448f5 100644
--- a/release/scripts/startup/bl_ui/properties_freestyle.py
+++ b/release/scripts/startup/bl_ui/properties_freestyle.py
@@ -122,7 +122,9 @@ class RENDERLAYER_PT_freestyle(RenderLayerFreestyleButtonsPanel, Panel):
layout.active = rl.use_freestyle
+ row = layout.row()
layout.prop(freestyle, "mode", text="Control mode")
+ layout.prop(freestyle, "use_view_map_cache", text="View Map Cache")
layout.label(text="Edge Detection Options:")
split = layout.split()
@@ -579,6 +581,20 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
sub.prop(linestyle, "split_dash3", text="D3")
sub.prop(linestyle, "split_gap3", text="G3")
+ ## Sorting
+ layout.prop(linestyle, "use_sorting", text="Sorting:")
+ col = layout.column()
+ col.active = linestyle.use_sorting
+ row = col.row(align=True)
+ row.prop(linestyle, "sort_key", text="")
+ sub = row.row()
+ sub.active = linestyle.sort_key in {'DISTANCE_FROM_CAMERA',
+ 'PROJECTED_X',
+ 'PROJECTED_Y'}
+ sub.prop(linestyle, "integration_type", text="")
+ row = col.row(align=True)
+ row.prop(linestyle, "sort_order", expand=True)
+
## Selection
layout.label(text="Selection:")
split = layout.split(align=True)
@@ -589,25 +605,18 @@ class RENDERLAYER_PT_freestyle_linestyle(RenderLayerFreestyleEditorButtonsPanel,
sub = row.row()
sub.active = linestyle.use_length_min
sub.prop(linestyle, "length_min")
- # Second column
- col = split.column()
row = col.row(align=True)
row.prop(linestyle, "use_length_max", text="")
sub = row.row()
sub.active = linestyle.use_length_max
sub.prop(linestyle, "length_max")
-
- ## Sorting
- layout.prop(linestyle, "use_sorting", text="Sorting:")
- col = layout.column()
- col.active = linestyle.use_sorting
+ # Second column
+ col = split.column()
row = col.row(align=True)
- row.prop(linestyle, "sort_key", text="")
+ row.prop(linestyle, "use_chain_count", text="")
sub = row.row()
- sub.active = linestyle.sort_key in {'DISTANCE_FROM_CAMERA'}
- sub.prop(linestyle, "integration_type", text="")
- row = col.row(align=True)
- row.prop(linestyle, "sort_order", expand=True)
+ sub.active = linestyle.use_chain_count
+ sub.prop(linestyle, "chain_count")
## Caps
layout.label(text="Caps:")
diff --git a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
index 5dd1f94747c..4789d119192 100644
--- a/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
+++ b/release/scripts/startup/bl_ui/properties_grease_pencil_common.py
@@ -47,4 +47,3 @@ class GreasePencilPanel():
col.label(text="Measure:")
col.operator("view3d.ruler")
-
diff --git a/release/scripts/startup/bl_ui/properties_object.py b/release/scripts/startup/bl_ui/properties_object.py
index e6d6a3952ea..25367a58a54 100644
--- a/release/scripts/startup/bl_ui/properties_object.py
+++ b/release/scripts/startup/bl_ui/properties_object.py
@@ -151,6 +151,7 @@ class OBJECT_PT_relations(ObjectButtonsPanel, Panel):
sub.prop_search(ob, "parent_bone", parent.data, "bones", text="")
sub.active = (parent is not None)
+
class GROUP_MT_specials(Menu):
bl_label = "Group Specials"
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 5c758b6568b..f1042856e4c 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -36,7 +36,10 @@ class UnifiedPaintPanel():
elif context.weight_paint_object:
return toolsettings.weight_paint
elif context.image_paint_object:
- return toolsettings.image_paint
+ if (toolsettings.image_paint and toolsettings.image_paint.detect_data()):
+ return toolsettings.image_paint
+
+ return None
elif context.particle_edit_object:
return toolsettings.particle_edit
@@ -170,7 +173,7 @@ def brush_texpaint_common(panel, context, layout, brush, settings, projpaint=Fal
mat = ob.active_material
if mat:
- col.label("Clone Slot")
+ col.label("Source Clone Slot")
col.template_list("TEXTURE_UL_texpaintslots", "",
mat, "texture_paint_images",
mat, "paint_clone_slot", rows=2)
@@ -179,18 +182,14 @@ def brush_texpaint_common(panel, context, layout, brush, settings, projpaint=Fal
mesh = ob.data
clone_text = mesh.uv_texture_clone.name if mesh.uv_texture_clone else ""
- col.label("Image")
+ col.label("Source Clone Image")
col.template_ID(settings, "clone_image")
- col.label("UV Map")
+ col.label("Source Clone UV Map")
col.menu("VIEW3D_MT_tools_projectpaint_clone", text=clone_text, translate=False)
-
-
else:
col.prop(brush, "clone_image", text="Image")
col.prop(brush, "clone_alpha", text="Alpha")
-
-
col.separator()
if capabilities.has_radius:
diff --git a/release/scripts/startup/bl_ui/space_clip.py b/release/scripts/startup/bl_ui/space_clip.py
index 13aad4c3888..3382633af60 100644
--- a/release/scripts/startup/bl_ui/space_clip.py
+++ b/release/scripts/startup/bl_ui/space_clip.py
@@ -260,7 +260,7 @@ class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
def draw(self, context):
layout = self.layout
- sc = context.space_data
+ # sc = context.space_data
# clip = sc.clip
col = layout.column(align=True)
diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py
index 8fd0ded17f7..927e517ef21 100644
--- a/release/scripts/startup/bl_ui/space_image.py
+++ b/release/scripts/startup/bl_ui/space_image.py
@@ -154,6 +154,7 @@ class IMAGE_MT_brush(Menu):
ups = context.tool_settings.unified_paint_settings
layout.prop(ups, "use_unified_size", text="Unified Size")
layout.prop(ups, "use_unified_strength", text="Unified Strength")
+ layout.prop(ups, "use_unified_color", text="Unified Color")
layout.separator()
# brush tool
@@ -1014,11 +1015,13 @@ class IMAGE_UV_sculpt(Panel, ImagePaintPanel):
col = layout.column()
col.prop(toolsettings, "uv_sculpt_lock_borders")
col.prop(toolsettings, "uv_sculpt_all_islands")
- col.prop(toolsettings, "uv_sculpt_tool")
+ col.prop(toolsettings, "uv_sculpt_tool")
if toolsettings.uv_sculpt_tool == 'RELAX':
col.prop(toolsettings, "uv_relax_method")
+ col.prop(uvsculpt, "show_brush")
+
class IMAGE_PT_tools_mask(MASK_PT_tools, Panel):
bl_space_type = 'IMAGE_EDITOR'
diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py
index e8914a3e9b0..24e8d2e4a53 100644
--- a/release/scripts/startup/bl_ui/space_node.py
+++ b/release/scripts/startup/bl_ui/space_node.py
@@ -200,7 +200,7 @@ class NODE_MT_select(Menu):
layout.separator()
- layout.operator("node.select_same_type")
+ layout.operator("node.select_grouped")
layout.operator("node.select_same_type_step").prev = True
layout.operator("node.select_same_type_step").prev = False
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index bbb1e41beb1..ce00d4eb8e7 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -215,7 +215,7 @@ class SEQUENCER_MT_select(Menu):
op = layout.operator("sequencer.select", text="All strips to the Right")
op.left_right = 'RIGHT'
op.linked_time = True
-
+
layout.separator()
layout.operator("sequencer.select_handles", text="Surrounding Handles").side = 'BOTH'
layout.operator("sequencer.select_handles", text="Left Handle").side = 'LEFT'
@@ -259,6 +259,7 @@ class SEQUENCER_MT_frame(Menu):
layout.operator("anim.previewrange_clear")
layout.operator("anim.previewrange_set")
+
class SEQUENCER_MT_add(Menu):
bl_label = "Add"
@@ -607,7 +608,7 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
col = layout.column(align=True)
if strip.type == 'SPEED':
col.prop(strip, "multiply_speed")
- elif strip.type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER','ALPHA_UNDER','OVER_DROP'}:
+ elif strip.type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
col.prop(strip, "use_default_fade", "Default fade")
if not strip.use_default_fade:
col.prop(strip, "effect_fader", text="Effect fader")
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 999e41e17f7..dc18dd73abc 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -383,6 +383,11 @@ class USERPREF_PT_system(Panel):
col = colsplit.column()
col.label(text="General:")
col.prop(system, "dpi")
+ col.label("Virtual Pixel Mode:")
+ col.prop(system, "virtual_pixel_mode", text="")
+
+ col.separator()
+
col.prop(system, "frame_server_port")
col.prop(system, "scrollback", text="Console Scrollback")
@@ -424,7 +429,6 @@ class USERPREF_PT_system(Panel):
col.prop(system, "use_gpu_mipmap")
col.prop(system, "use_16bit_textures")
-
if system.is_occlusion_query_supported():
col.separator()
col.label(text="Selection")
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 61d359ebdac..2249d2b04b8 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -608,6 +608,19 @@ class VIEW3D_MT_select_particle(Menu):
layout.operator("particle.select_tips", text="Tips")
+class VIEW3D_MT_edit_mesh_select_similar(Menu):
+ bl_label = "Select Similar"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator_enum("mesh.select_similar", "type")
+
+ layout.separator()
+
+ layout.operator("mesh.select_similar_region", text="Face Regions")
+
+
class VIEW3D_MT_select_edit_mesh(Menu):
bl_label = "Select"
@@ -647,7 +660,7 @@ class VIEW3D_MT_select_edit_mesh(Menu):
layout.separator()
# other ...
- layout.operator_menu_enum("mesh.select_similar", "type", text="Similar")
+ layout.menu("VIEW3D_MT_edit_mesh_select_similar")
layout.operator("mesh.select_ungrouped", text="Ungrouped Verts")
layout.separator()
@@ -1424,6 +1437,8 @@ class VIEW3D_MT_brush(Menu):
ups = context.tool_settings.unified_paint_settings
layout.prop(ups, "use_unified_size", text="Unified Size")
layout.prop(ups, "use_unified_strength", text="Unified Strength")
+ if context.image_paint_object or context.vertex_paint_object:
+ layout.prop(ups, "use_unified_color", text="Unified Color")
layout.separator()
# brush paint modes
@@ -2198,7 +2213,6 @@ class VIEW3D_MT_edit_mesh_edges(Menu):
layout = self.layout
with_freestyle = bpy.app.build_options.freestyle
- scene = context.scene
layout.operator_context = 'INVOKE_REGION_WIN'
@@ -2254,7 +2268,6 @@ class VIEW3D_MT_edit_mesh_faces(Menu):
layout = self.layout
with_freestyle = bpy.app.build_options.freestyle
- scene = context.scene
layout.operator_context = 'INVOKE_REGION_WIN'
@@ -2951,7 +2964,7 @@ class VIEW3D_PT_view3d_meshdisplay(Panel):
sub = row.row(align=True)
sub.active = mesh.show_normal_vertex or mesh.show_normal_face or mesh.show_normal_loop
- sub.prop(context.scene.tool_settings, "normal_size", text="Size")
+ sub.prop(scene.tool_settings, "normal_size", text="Size")
col.separator()
split = layout.split()
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 6b0c5b1e993..213bfd9d808 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -775,6 +775,65 @@ class View3DPaintPanel(UnifiedPaintPanel):
bl_space_type = 'VIEW_3D'
bl_region_type = 'TOOLS'
+class VIEW3D_PT_imapaint_tools_missing(Panel, View3DPaintPanel):
+ bl_category = "Tools"
+ bl_label = "Missing Data"
+
+ @classmethod
+ def poll(cls, context):
+ toolsettings = context.tool_settings.image_paint
+ return context.image_paint_object and not toolsettings.detect_data()
+
+ def draw(self, context):
+ layout = self.layout
+ toolsettings = context.tool_settings.image_paint
+
+ col = layout.column()
+ col.label("Missing Data", icon='ERROR')
+ if toolsettings.missing_uvs:
+ col.separator()
+ col.label("Missing UVs", icon='INFO')
+ col.label("Unwrap the mesh in edit mode or generate a simple UVs")
+ col.operator("mesh.uv_texture_add", text="Add Simple UVs")
+
+ if toolsettings.mode == 'MATERIAL':
+ if toolsettings.missing_materials:
+ col.separator()
+ col.label("Missing Materials", icon='INFO')
+ col.label("Add a material and paint slot below")
+ col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
+
+ elif toolsettings.missing_texture:
+ ob = context.active_object
+ mat = ob.active_material
+
+ col.separator()
+ if mat:
+ col.label("Missing Texture Slots", icon='INFO')
+ col.label("Add a paint slot below")
+ col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
+ else:
+ col.label("Missing Materials", icon='INFO')
+ col.label("Add a material and paint slot below")
+ col.operator_menu_enum("paint.add_texture_paint_slot", "type", text="Add Paint Slot")
+
+
+ elif toolsettings.mode == 'IMAGE':
+ if toolsettings.missing_texture:
+ col.separator()
+ col.label("Missing Canvas", icon='INFO')
+ col.label("Add or assign a canvas image below")
+ col.label("Canvas Image")
+ col.template_ID(toolsettings, "canvas")
+ col.operator("image.new", text="New").gen_context = 'PAINT_CANVAS'
+
+ if toolsettings.missing_stencil:
+ col.separator()
+ col.label("Missing Stencil", icon='INFO')
+ col.label("Add or assign a stencil image below")
+ col.label("Stencil Image")
+ col.template_ID(toolsettings, "stencil_image")
+ col.operator("image.new", text="New").gen_context = 'PAINT_STENCIL'
class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
bl_category = "Tools"
@@ -844,14 +903,15 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel):
self.prop_unified_size(row, context, brush, "use_pressure_size")
# strength, use_strength_pressure, and use_strength_attenuation
- if capabilities.has_strength:
- col.separator()
- row = col.row(align=True)
+ col.separator()
+ row = col.row(align=True)
- if capabilities.has_space_attenuation:
- row.prop(brush, "use_space_attenuation", toggle=True, icon_only=True)
+ if capabilities.has_space_attenuation:
+ row.prop(brush, "use_space_attenuation", toggle=True, icon_only=True)
+
+ self.prop_unified_strength(row, context, brush, "strength", text="Strength")
- self.prop_unified_strength(row, context, brush, "strength", text="Strength")
+ if capabilities.has_strength_pressure:
self.prop_unified_strength(row, context, brush, "use_pressure_strength")
# auto_smooth_factor and use_inverse_smooth_pressure
@@ -1005,6 +1065,17 @@ class TEXTURE_UL_texpaintslots(UIList):
layout.alignment = 'CENTER'
layout.label(text="")
+class VIEW3D_MT_tools_projectpaint_uvlayer(Menu):
+ bl_label = "Clone Layer"
+
+ def draw(self, context):
+ layout = self.layout
+
+ for i, tex in enumerate(context.active_object.data.uv_textures):
+ props = layout.operator("wm.context_set_int", text=tex.name, translate=False)
+ props.data_path = "active_object.data.uv_textures.active_index"
+ props.value = i
+
class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
bl_context = "imagepaint"
@@ -1027,7 +1098,7 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
col = layout.column()
col.label("Painting Mode")
- col.prop(settings, "mode", text = "")
+ col.prop(settings, "mode", text="")
col.separator()
if settings.mode == 'MATERIAL':
@@ -1058,16 +1129,21 @@ class VIEW3D_PT_slots_projectpaint(View3DPanel, Panel):
col.prop_search(slot, "uv_layer", ob.data, "uv_textures", text="")
elif settings.mode == 'IMAGE':
+ mesh = ob.data
+ uv_text = mesh.uv_textures.active.name if mesh.uv_textures.active else ""
+ col.label("Canvas Image")
col.template_ID(settings, "canvas")
+ col.operator("image.new", text="New").gen_context = 'PAINT_CANVAS'
+ col.label("UV Map")
+ col.menu("VIEW3D_MT_tools_projectpaint_uvlayer", text=uv_text, translate=False)
col.separator()
col.operator("image.save_dirty", text="Save All Images")
-
class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel):
bl_context = "imagepaint"
- bl_label = "Stencil"
+ bl_label = "Mask"
bl_category = "Slots"
@classmethod
@@ -1095,9 +1171,10 @@ class VIEW3D_PT_stencil_projectpaint(View3DPanel, Panel):
col.label("UV Map")
col.menu("VIEW3D_MT_tools_projectpaint_stencil", text=stencil_text, translate=False)
- col.label("Image")
- row = col.row(align=True)
- row.template_ID(ipaint, "stencil_image")
+ col.label("Stencil Image")
+ col.template_ID(ipaint, "stencil_image")
+ col.operator("image.new", text="New").gen_context = 'PAINT_STENCIL'
+
col.label("Visualization")
row = col.row(align=True)
@@ -1195,7 +1272,7 @@ class VIEW3D_PT_tools_brush_texture(Panel, View3DPaintPanel):
brush_texture_settings(col, brush, context.sculpt_object)
-class VIEW3D_PT_tools_mask_texture(View3DPanel, Panel):
+class VIEW3D_PT_tools_mask_texture(View3DPanel, View3DPaintPanel):
bl_category = "Tools"
bl_context = "imagepaint"
bl_label = "Texture Mask"
@@ -1203,8 +1280,8 @@ class VIEW3D_PT_tools_mask_texture(View3DPanel, Panel):
@classmethod
def poll(cls, context):
- brush = context.tool_settings.image_paint.brush
- return (context.image_paint_object and brush)
+ settings = cls.paint_settings(context)
+ return (settings and settings.image_paint.brush and context.image_paint_object and brush)
def draw(self, context):
layout = self.layout
@@ -1459,11 +1536,8 @@ class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel):
@classmethod
def poll(cls, context):
- toolsettings = context.tool_settings
- return ((context.sculpt_object and toolsettings.sculpt) or
- (context.vertex_paint_object and toolsettings.vertex_paint) or
- (context.weight_paint_object and toolsettings.weight_paint) or
- (context.image_paint_object and toolsettings.image_paint))
+ settings = cls.paint_settings(context)
+ return settings
def draw(self, context):
layout = self.layout
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 5dccda789e0..8c2476bd430 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -112,6 +112,20 @@ def line_style_shader_nodes_poll(context):
snode.shader_type == 'LINESTYLE')
+# only show nodes working in world node trees
+def world_shader_nodes_poll(context):
+ snode = context.space_data
+ return (snode.tree_type == 'ShaderNodeTree' and
+ snode.shader_type == 'WORLD')
+
+
+# only show nodes working in object node trees
+def object_shader_nodes_poll(context):
+ snode = context.space_data
+ return (snode.tree_type == 'ShaderNodeTree' and
+ snode.shader_type == 'OBJECT')
+
+
# All standard node categories currently used in nodes.
shader_node_categories = [
@@ -180,30 +194,30 @@ shader_node_categories = [
NodeItem("NodeGroupInput", poll=group_input_output_item_poll),
]),
ShaderNewNodeCategory("SH_NEW_OUTPUT", "Output", items=[
- NodeItem("ShaderNodeOutputMaterial"),
- NodeItem("ShaderNodeOutputLamp"),
- NodeItem("ShaderNodeOutputWorld"),
+ NodeItem("ShaderNodeOutputMaterial", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeOutputLamp", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeOutputWorld", poll=world_shader_nodes_poll),
NodeItem("ShaderNodeOutputLineStyle", poll=line_style_shader_nodes_poll),
NodeItem("NodeGroupOutput", poll=group_input_output_item_poll),
]),
ShaderNewNodeCategory("SH_NEW_SHADER", "Shader", items=[
NodeItem("ShaderNodeMixShader"),
NodeItem("ShaderNodeAddShader"),
- NodeItem("ShaderNodeBsdfDiffuse"),
- NodeItem("ShaderNodeBsdfGlossy"),
- NodeItem("ShaderNodeBsdfTransparent"),
- NodeItem("ShaderNodeBsdfRefraction"),
- NodeItem("ShaderNodeBsdfGlass"),
- NodeItem("ShaderNodeBsdfTranslucent"),
- NodeItem("ShaderNodeBsdfAnisotropic"),
- NodeItem("ShaderNodeBsdfVelvet"),
- NodeItem("ShaderNodeBsdfToon"),
- NodeItem("ShaderNodeSubsurfaceScattering"),
- NodeItem("ShaderNodeEmission"),
- NodeItem("ShaderNodeBsdfHair"),
- NodeItem("ShaderNodeBackground"),
- NodeItem("ShaderNodeAmbientOcclusion"),
- NodeItem("ShaderNodeHoldout"),
+ NodeItem("ShaderNodeBsdfDiffuse", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfGlossy", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfTransparent", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfRefraction", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfGlass", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfTranslucent", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfAnisotropic", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfVelvet", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfToon", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeSubsurfaceScattering", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeEmission", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfHair", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeBackground", poll=world_shader_nodes_poll),
+ NodeItem("ShaderNodeAmbientOcclusion", poll=object_shader_nodes_poll),
+ NodeItem("ShaderNodeHoldout", poll=object_shader_nodes_poll),
NodeItem("ShaderNodeVolumeAbsorption"),
NodeItem("ShaderNodeVolumeScatter"),
]),
diff --git a/release/scripts/templates_osl/fresnel_conductive.osl b/release/scripts/templates_osl/fresnel_conductive.osl
index c197656eaee..6de0692bffe 100644
--- a/release/scripts/templates_osl/fresnel_conductive.osl
+++ b/release/scripts/templates_osl/fresnel_conductive.osl
@@ -16,14 +16,14 @@
color fresnel_conductor(float cosi, color eta, color k)
{
- color cosi2 = color(cosi*cosi);
+ color cosi2 = color(cosi * cosi);
color one = color(1, 1, 1);
color tmp_f = eta * eta + k * k;
color tmp = tmp_f * cosi2;
color Rparl2 = (tmp - (2.0 * eta * cosi) + one) /
- (tmp + (2.0 * eta * cosi) + one);
+ (tmp + (2.0 * eta * cosi) + one);
color Rperp2 = (tmp_f - (2.0 * eta * cosi) + cosi2) /
- (tmp_f + (2.0 * eta * cosi) + cosi2);
+ (tmp_f + (2.0 * eta * cosi) + cosi2);
return (Rparl2 + Rperp2) * 0.5;
}
diff --git a/release/scripts/templates_osl/westin_closure.osl b/release/scripts/templates_osl/westin_closure.osl
deleted file mode 100644
index 8d90f3aa306..00000000000
--- a/release/scripts/templates_osl/westin_closure.osl
+++ /dev/null
@@ -1,12 +0,0 @@
-
-shader node_westin_bsdf(
- color Color = 0.8,
- float Roughness = 0.5,
- float Edginess = 0.2,
- normal Normal = N,
- output closure color Sheen = 0,
- output closure color Backscatter = 0)
-{
- Sheen = Color * westin_sheen(Normal, Roughness);
- Backscatter = Color * westin_backscatter(Normal, Edginess);
-} \ No newline at end of file
diff --git a/release/scripts/templates_py/batch_export.py b/release/scripts/templates_py/batch_export.py
index 45d26f4b525..6c77c5d6a1a 100644
--- a/release/scripts/templates_py/batch_export.py
+++ b/release/scripts/templates_py/batch_export.py
@@ -9,6 +9,9 @@ basedir = os.path.dirname(bpy.data.filepath)
if not basedir:
raise Exception("Blend file is not saved")
+scene = bpy.context.scene
+
+obj_active = scene.objects.active
selection = bpy.context.selected_objects
bpy.ops.object.select_all(action='DESELECT')
@@ -17,6 +20,9 @@ for obj in selection:
obj.select = True
+ # some exporters only use the active object
+ scene.objects.active = obj
+
name = bpy.path.clean_name(obj.name)
fn = os.path.join(basedir, name)
@@ -29,5 +35,8 @@ for obj in selection:
print("written:", fn)
+
+scene.objects.active = obj_active
+
for obj in selection:
obj.select = True
diff --git a/release/scripts/templates_py/operator_modal_view3d_raycast.py b/release/scripts/templates_py/operator_modal_view3d_raycast.py
index 4d0355047f4..1aa13c90ca3 100644
--- a/release/scripts/templates_py/operator_modal_view3d_raycast.py
+++ b/release/scripts/templates_py/operator_modal_view3d_raycast.py
@@ -1,9 +1,8 @@
import bpy
-from mathutils import Vector
from bpy_extras import view3d_utils
-def main(context, event, ray_max=10000.0):
+def main(context, event, ray_max=1000.0):
"""Run this function on left mouse, execute the ray cast"""
# get the context arguments
scene = context.scene
@@ -14,6 +13,11 @@ def main(context, event, ray_max=10000.0):
# get the ray from the viewport and mouse
view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
+
+ if rv3d.view_perspective == 'ORTHO':
+ # move ortho origin back
+ ray_origin = ray_origin - (view_vector * (ray_max / 2.0))
+
ray_target = ray_origin + (view_vector * ray_max)
def visible_objects_and_duplis():
@@ -106,4 +110,3 @@ def unregister():
if __name__ == "__main__":
register()
-
diff --git a/release/scripts/templates_py/script_stub.py b/release/scripts/templates_py/script_stub.py
index 3f56749f3b3..5505ca64078 100644
--- a/release/scripts/templates_py/script_stub.py
+++ b/release/scripts/templates_py/script_stub.py
@@ -11,4 +11,3 @@ filepath = os.path.join(os.path.dirname(bpy.data.filepath), filename)
global_namespace = {"__file__": filepath, "__name__": "__main__"}
with open(filepath, 'rb') as file:
exec(compile(file.read(), filepath, 'exec'), global_namespace)
-
diff --git a/release/scripts/templates_py/ui_pie_menu.py b/release/scripts/templates_py/ui_pie_menu.py
index 87500b682d6..0c431ca50ff 100644
--- a/release/scripts/templates_py/ui_pie_menu.py
+++ b/release/scripts/templates_py/ui_pie_menu.py
@@ -29,4 +29,3 @@ if __name__ == "__main__":
register()
bpy.ops.wm.call_menu_pie(name="VIEW3D_PIE_template")
-
diff --git a/scons b/scons
-Subproject 1ec93106c40fab0c339d09c7ed9897c85ddf3da
+Subproject 625d446ae8996ff1b3d660c44e2827fc832cf12
diff --git a/source/blender/avi/intern/avi_rgb.c b/source/blender/avi/intern/avi_rgb.c
index c6a78eccce2..632ecad61a6 100644
--- a/source/blender/avi/intern/avi_rgb.c
+++ b/source/blender/avi/intern/avi_rgb.c
@@ -123,13 +123,12 @@ void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, unsigned char *buffe
(void)stream; /* unused */
- *size = movie->header->Height * movie->header->Width * 3;
- if (movie->header->Width % 2) *size += movie->header->Height;
-
- buf = MEM_mallocN(*size, "toavirgbbuf");
-
rowstride = movie->header->Width * 3;
- if (movie->header->Width % 2) rowstride++;
+ /* AVI files has uncompressed lines 4-byte aligned */
+ rowstride = (rowstride + 3) & ~3;
+
+ *size = movie->header->Height * rowstride;
+ buf = MEM_mallocN(*size, "toavirgbbuf");
for (y = 0; y < movie->header->Height; y++) {
memcpy(&buf[y * rowstride], &buffer[((movie->header->Height - 1) - y) * movie->header->Width * 3], movie->header->Width * 3);
diff --git a/source/blender/avi/intern/avi_rgb32.c b/source/blender/avi/intern/avi_rgb32.c
index 5c7a4889d97..c9cbcb05bb8 100644
--- a/source/blender/avi/intern/avi_rgb32.c
+++ b/source/blender/avi/intern/avi_rgb32.c
@@ -74,8 +74,8 @@ void *avi_converter_to_rgb32(AviMovie *movie, int stream, unsigned char *buffer,
(void)stream; /* unused */
- buf = MEM_mallocN(movie->header->Height * movie->header->Width * 4, "torgb32buf");
*size = movie->header->Height * movie->header->Width * 4;
+ buf = MEM_mallocN(*size, "torgb32buf");
memset(buf, 255, *size);
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 80d2750fe82..e79822daa4d 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -37,8 +37,10 @@ struct Main;
struct AnimData;
struct KeyingSet;
struct KS_Path;
+struct bContext;
struct PointerRNA;
+struct PropertyRNA;
struct ReportList;
struct bAction;
struct bActionGroup;
@@ -127,6 +129,9 @@ void BKE_animdata_separate_by_basepath(struct ID *srcID, struct ID *dstID, struc
/* Move F-Curves from src to destination if it's path is based on basepath */
void action_move_fcurves_by_basepath(struct bAction *srcAct, struct bAction *dstAct, const char basepath[]);
+char *BKE_animdata_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
+ char *base_path);
+
/* ************************************* */
/* Batch AnimData API */
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 46a0c36a5f2..6c8f90c60ae 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -41,8 +41,8 @@ extern "C" {
/* these lines are grep'd, watch out for our not-so-awesome regex
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
-#define BLENDER_VERSION 271
-#define BLENDER_SUBVERSION 6
+#define BLENDER_VERSION 272
+#define BLENDER_SUBVERSION 1
/* 262 was the last editmesh release but it has compatibility code for bmesh data */
#define BLENDER_MINVERSION 270
#define BLENDER_MINSUBVERSION 5
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h
index 5a1e173f0b3..9a6524cc9ab 100644
--- a/source/blender/blenkernel/BKE_customdata.h
+++ b/source/blender/blenkernel/BKE_customdata.h
@@ -310,7 +310,7 @@ void CustomData_set_layer_flag(struct CustomData *data, int type, int flag);
void CustomData_bmesh_set_default(struct CustomData *data, void **block);
void CustomData_bmesh_free_block(struct CustomData *data, void **block);
-void CustomData_bmesh_free_block_data(struct CustomData *data, void **block);
+void CustomData_bmesh_free_block_data(struct CustomData *data, void *block);
/* copy custom data to/from layers as in mesh/derivedmesh, to editmesh
* blocks of data. the CustomData's must not be compatible */
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 0e86be9b97c..c377769b271 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -43,6 +43,7 @@ struct DriverVar;
struct DriverTarget;
struct FCM_EnvelopeData;
+struct bContext;
struct bAction;
struct BezTriple;
struct StructRNA;
@@ -221,8 +222,12 @@ struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, c
*/
int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix, const char *dataName);
-/* find an f-curve based on an rna property */
-struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex, struct bAction **action, bool *r_driven);
+/* find an f-curve based on an rna property. */
+struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop, int rnaindex,
+ struct bAction **action, bool *r_driven);
+/* Same as above, but takes a context data, temp hack needed for complex paths like texture ones. */
+struct FCurve *rna_get_fcurve_context_ui(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop,
+ int rnaindex, struct bAction **action, bool *r_driven);
/* Binary search algorithm for finding where to 'insert' BezTriple with given frame number.
* Returns the index to insert at (data already at that index will be offset if replace is 0)
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 1d37f9e64e1..500c2813a75 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -71,8 +71,8 @@ void id_clear_lib_data(struct Main *bmain, struct ID *id);
struct ListBase *which_libbase(struct Main *mainlib, short type);
-#define MAX_LIBARRAY 43
-int set_listbasepointers(struct Main *main, struct ListBase **lb);
+#define MAX_LIBARRAY 35
+int set_listbasepointers(struct Main *main, struct ListBase *lb[MAX_LIBARRAY]);
void BKE_libblock_free(struct Main *bmain, void *idv);
void BKE_libblock_free_ex(struct Main *bmain, void *idv, bool do_id_user);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index a81da8c18af..b080ca37e67 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -50,6 +50,7 @@ struct PaintCurve;
struct Palette;
struct PaletteColor;
struct PBVH;
+struct ReportList;
struct Scene;
struct Sculpt;
struct StrokeCache;
@@ -100,7 +101,6 @@ void BKE_paint_set_overlay_override(enum OverlayFlags flag);
void BKE_palette_free(struct Palette *palette);
struct Palette *BKE_palette_add(struct Main *bmain, const char *name);
struct PaletteColor *BKE_palette_color_add(struct Palette *palette);
-void BKE_palette_color_delete(struct Palette *palette);
bool BKE_palette_is_empty(const struct Palette *palette);
void BKE_palette_color_remove(struct Palette *palette, struct PaletteColor *color);
void BKE_palette_cleanup(struct Palette *palette);
@@ -122,6 +122,9 @@ struct Palette *BKE_paint_palette(struct Paint *paint);
void BKE_paint_palette_set(struct Paint *p, struct Palette *palette);
void BKE_paint_curve_set(struct Brush *br, struct PaintCurve *pc);
+void BKE_paint_data_warning(struct ReportList *reports, bool uvs, bool mat, bool tex, bool stencil);
+bool BKE_paint_proj_mesh_data_check(struct Scene *scene, struct Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil);
+
/* testing face select mode
* Texture paint could be removed since selected faces are not used
* however hiding faces is useful */
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 9ff9991f5a6..81c03d8081b 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2602,8 +2602,6 @@ static void make_vertexcos__mapFunc(void *userData, int index, const float co[3]
void mesh_get_mapped_verts_coords(DerivedMesh *dm, float (*r_cos)[3], const int totcos)
{
- float (*vertexcos)[3];
-
if (dm->foreachMappedVert) {
MappedUserData userData;
memset(r_cos, 0, sizeof(*r_cos) * totcos);
@@ -2615,7 +2613,7 @@ void mesh_get_mapped_verts_coords(DerivedMesh *dm, float (*r_cos)[3], const int
else {
int i;
for (i = 0; i < totcos; i++) {
- dm->getVertCo(dm, i, vertexcos[i]);
+ dm->getVertCo(dm, i, r_cos[i]);
}
}
}
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 5ee82bb5842..2fb832dc72d 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -51,18 +51,23 @@
#include "DNA_material_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
#include "BKE_animsys.h"
#include "BKE_action.h"
+#include "BKE_context.h"
#include "BKE_depsgraph.h"
#include "BKE_fcurve.h"
#include "BKE_nla.h"
#include "BKE_global.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_library.h"
#include "BKE_report.h"
+#include "BKE_texture.h"
#include "RNA_access.h"
@@ -551,6 +556,74 @@ void BKE_animdata_separate_by_basepath(ID *srcID, ID *dstID, ListBase *basepaths
}
}
+/**
+ * Temporary wrapper for driver operators for buttons to make it easier to create
+ * such drivers by rerouting all paths through the active object instead so that
+ * they will get picked up by the dependency system.
+ *
+ * \param C Context pointer - for getting active data
+ * \param[in,out] ptr RNA pointer for property's datablock. May be modified as result of path remapping.
+ * \param prop RNA definition of property to add for
+ * \return MEM_alloc'd string representing the path to the property from the given #PointerRNA
+ */
+char *BKE_animdata_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop, char *base_path)
+{
+ ID *id = (ID *)ptr->id.data;
+ ScrArea *sa = CTX_wm_area(C);
+
+ /* get standard path which may be extended */
+ char *basepath = base_path ? base_path : RNA_path_from_ID_to_property(ptr, prop);
+ char *path = basepath; /* in case no remapping is needed */
+
+ /* Remapping will only be performed in the Properties Editor, as only this
+ * restricts the subspace of options to the 'active' data (a manageable state)
+ */
+ /* TODO: watch out for pinned context? */
+ if ((sa) && (sa->spacetype == SPACE_BUTS)) {
+ Object *ob = CTX_data_active_object(C);
+
+ if (ob && id) {
+ /* only id-types which can be remapped to go through objects should be considered */
+ switch (GS(id->name)) {
+ case ID_TE: /* textures */
+ {
+ Material *ma = give_current_material(ob, ob->actcol);
+ Tex *tex = give_current_material_texture(ma);
+
+ /* assumes: texture will only be shown if it is active material's active texture it's ok */
+ if ((ID *)tex == id) {
+ char name_esc_ma[(sizeof(ma->id.name) - 2) * 2];
+ char name_esc_tex[(sizeof(tex->id.name) - 2) * 2];
+
+ BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma));
+ BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex));
+
+ /* create new path */
+ // TODO: use RNA path functions to construct step by step instead?
+ // FIXME: maybe this isn't even needed anymore...
+ path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s",
+ name_esc_ma, name_esc_tex, basepath);
+
+ /* free old one */
+ if (basepath != base_path)
+ MEM_freeN(basepath);
+ }
+ break;
+ }
+ }
+
+ /* fix RNA pointer, as we've now changed the ID root by changing the paths */
+ if (basepath != path) {
+ /* rebase provided pointer so that it starts from object... */
+ RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
+ }
+ }
+ }
+
+ /* the path should now have been corrected for use */
+ return path;
+}
+
/* Path Validation -------------------------------------------- */
/* Check if a given RNA Path is valid, by tracing it from the given ID, and seeing if we can resolve it */
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 16b5574709e..bb05b5de8a6 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -505,7 +505,7 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB
invert_m3_m3(imat3, mat3);
mul_m3_m3m3(mat3, result, imat3); /* the matrix transforming vec_roll to desired roll */
- roll1 = (float)atan2(mat3[2][0], mat3[2][2]);
+ roll1 = atan2f(mat3[2][0], mat3[2][2]);
}
}
else {
@@ -543,7 +543,7 @@ void b_bone_spline_setup(bPoseChannel *pchan, int rest, Mat4 result_array[MAX_BB
invert_m3_m3(imat3, mat3);
mul_m3_m3m3(mat3, imat3, result); /* the matrix transforming vec_roll to desired roll */
- roll2 = (float)atan2(mat3[2][0], mat3[2][2]);
+ roll2 = atan2f(mat3[2][0], mat3[2][2]);
/* and only now negate handle */
mul_v3_fl(h2, -hlength2);
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 6ce3abe7a32..1402f62291f 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -232,7 +232,7 @@ void BKE_camera_params_from_object(CameraParams *params, Object *ob)
/* lamp object */
Lamp *la = ob->data;
float fac = cosf(la->spotsize * 0.5f);
- float phi = acos(fac);
+ float phi = acosf(fac);
params->lens = 16.0f * fac / sinf(phi);
if (params->lens == 0.0f)
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 08052127fbf..bfc70c91181 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -552,7 +552,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm,
MVert *mvert = cddm->mvert;
MFace *mface = cddm->mface;
const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
- short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
+ const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
if (cddm->pbvh && cddm->pbvh_draw) {
@@ -673,9 +673,9 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm,
{
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
MVert *mv = cddm->mvert;
- MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
+ const MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
const float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
- short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
+ const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
MCol *mcol;
int i, orig;
@@ -940,7 +940,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm,
MFace *mf = cddm->mface;
MCol *mcol;
const float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL);
- short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
+ const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int colType, useColors = flag & DM_DRAW_USE_COLORS;
int i, orig;
@@ -1157,8 +1157,8 @@ static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag);
}
-static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert,
- short (*lnor)[3], int smoothnormal)
+static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, const MVert *mvert, int a, int index, int vert,
+ const short (*lnor)[3], const bool smoothnormal)
{
const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
int b;
@@ -1234,11 +1234,11 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
GPUVertexAttribs gattribs;
DMVertexAttribs attribs;
- MVert *mvert = cddm->mvert;
- MFace *mface = cddm->mface;
+ const MVert *mvert = cddm->mvert;
+ const MFace *mface = cddm->mface;
/* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
- float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
- short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
+ const float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, b, matnr, new_matnr;
bool do_draw;
int orig;
@@ -1277,8 +1277,8 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
glBegin(GL_QUADS);
for (a = 0; a < dm->numTessFaceData; a++, mface++) {
- const int smoothnormal = lnors || (mface->flag & ME_SMOOTH);
- short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL;
+ const bool smoothnormal = lnors || (mface->flag & ME_SMOOTH);
+ const short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL;
new_matnr = mface->mat_nr + 1;
if (new_matnr != matnr) {
@@ -1323,13 +1323,11 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
glNormal3fv(nor);
}
}
-
- if (lnors) {
- ln1 = &lnors[0][0];
- ln2 = &lnors[0][1];
- ln3 = &lnors[0][2];
- ln4 = &lnors[0][3];
- lnors++;
+ else if (lnors) {
+ ln1 = &lnors[a][0];
+ ln2 = &lnors[a][1];
+ ln3 = &lnors[a][2];
+ ln4 = &lnors[a][3];
}
cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, ln1, smoothnormal);
@@ -1350,7 +1348,7 @@ static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
int i;
- MFace *mf = mface;
+ const MFace *mf = mface;
GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
memset(&attribs, 0, sizeof(attribs));
@@ -1574,8 +1572,8 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
DMVertexAttribs attribs;
MVert *mvert = cddm->mvert;
MFace *mf = cddm->mface;
- float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
- short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
+ const float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
+ const short (*lnors)[4][3] = dm->getTessFaceDataArray(dm, CD_TESSLOOPNORMAL);
int a, matnr, new_matnr;
int orig;
@@ -1610,8 +1608,8 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
glBegin(GL_QUADS);
for (a = 0; a < dm->numTessFaceData; a++, mf++) {
- const int smoothnormal = lnors || (mf->flag & ME_SMOOTH);
- short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL;
+ const bool smoothnormal = lnors || (mf->flag & ME_SMOOTH);
+ const short (*ln1)[3] = NULL, (*ln2)[3] = NULL, (*ln3)[3] = NULL, (*ln4)[3] = NULL;
/* material */
new_matnr = mf->mat_nr + 1;
@@ -1650,13 +1648,11 @@ static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
glNormal3fv(nor);
}
}
-
- if (lnors) {
- ln1 = &lnors[0][0];
- ln2 = &lnors[0][1];
- ln3 = &lnors[0][2];
- ln4 = &lnors[0][3];
- lnors++;
+ else if (lnors) {
+ ln1 = &lnors[a][0];
+ ln2 = &lnors[a][1];
+ ln3 = &lnors[a][2];
+ ln4 = &lnors[a][3];
}
/* vertices */
@@ -2720,7 +2716,7 @@ static unsigned int poly_gset_hash_fn(const void *key)
return pk->hash_sum;
}
-static int poly_gset_compare_fn(const void *k1, const void *k2)
+static bool poly_gset_compare_fn(const void *k1, const void *k2)
{
const PolyKey *pk1 = k1;
const PolyKey *pk2 = k2;
@@ -3017,10 +3013,17 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
if (UNLIKELY(c == 0)) {
continue;
}
+ else if (UNLIKELY(c < 3)) {
+ STACK_DISCARD(oldl, c);
+ STACK_DISCARD(mloop, c);
+ continue;
+ }
+
mp_new = STACK_PUSH_RET_PTR(mpoly);
*mp_new = *mp;
mp_new->totloop = c;
+ BLI_assert(mp_new->totloop >= 3);
mp_new->loopstart = STACK_SIZE(mloop) - c;
STACK_PUSH(oldp, i);
@@ -3091,7 +3094,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
MEM_freeN(oldv);
MEM_freeN(olde);
MEM_freeN(oldl);
- MEM_freeN(oldp);;
+ MEM_freeN(oldp);
BLI_edgehash_free(ehash, NULL);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 885f186faf3..aacf02555d4 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -228,7 +228,7 @@ void bvhtree_update_from_cloth(ClothModifierData *clmd, int moving)
ClothVertex *verts = cloth->verts;
MFace *mfaces;
float co[12], co_moving[12];
- int ret = 0;
+ bool ret = false;
if (!bvhtree)
return;
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index cedd9eae597..2f600935b1e 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -110,7 +110,7 @@ void bvhtree_update_from_mvert(BVHTree *bvhtree, MFace *faces, int numfaces, MVe
int i;
MFace *mfaces = faces;
float co[12], co_moving[12];
- int ret = 0;
+ bool ret = false;
if ( !bvhtree )
return;
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index c6d07a959d1..a63e06c7cb8 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -577,14 +577,14 @@ static void curvemap_make_table(CurveMap *cuma, const rctf *clipr)
/* store first and last handle for extrapolation, unit length */
cuma->ext_in[0] = bezt[0].vec[0][0] - bezt[0].vec[1][0];
cuma->ext_in[1] = bezt[0].vec[0][1] - bezt[0].vec[1][1];
- range = sqrt(cuma->ext_in[0] * cuma->ext_in[0] + cuma->ext_in[1] * cuma->ext_in[1]);
+ range = sqrtf(cuma->ext_in[0] * cuma->ext_in[0] + cuma->ext_in[1] * cuma->ext_in[1]);
cuma->ext_in[0] /= range;
cuma->ext_in[1] /= range;
a = cuma->totpoint - 1;
cuma->ext_out[0] = bezt[a].vec[1][0] - bezt[a].vec[2][0];
cuma->ext_out[1] = bezt[a].vec[1][1] - bezt[a].vec[2][1];
- range = sqrt(cuma->ext_out[0] * cuma->ext_out[0] + cuma->ext_out[1] * cuma->ext_out[1]);
+ range = sqrtf(cuma->ext_out[0] * cuma->ext_out[0] + cuma->ext_out[1] * cuma->ext_out[1]);
cuma->ext_out[0] /= range;
cuma->ext_out[1] /= range;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index d80529ee780..ee7bad773fa 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -3592,7 +3592,7 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
cross_v3_v3v3(raxis, obvec, tarvec);
rangle = dot_v3v3(obvec, tarvec);
- rangle = acos(max_ff(-1.0f, min_ff(1.0f, rangle)));
+ rangle = acosf(max_ff(-1.0f, min_ff(1.0f, rangle)));
/* construct rotation matrix from the axis-angle rotation found above
* - this call takes care to make sure that the axis provided is a unit vector first
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index a06834f61b3..ca58035d638 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -2468,7 +2468,7 @@ static void make_bevel_list_2D(BevList *bl)
/* first */
bevp = bl->bevpoints;
- angle = atan2(bevp->dir[0], bevp->dir[1]) - M_PI / 2.0;
+ angle = atan2f(bevp->dir[0], bevp->dir[1]) - (float)(M_PI / 2.0f);
bevp->sina = sinf(angle);
bevp->cosa = cosf(angle);
vec_to_quat(bevp->quat, bevp->dir, 5, 1);
@@ -2476,7 +2476,7 @@ static void make_bevel_list_2D(BevList *bl)
/* last */
bevp = bl->bevpoints;
bevp += (bl->nr - 1);
- angle = atan2(bevp->dir[0], bevp->dir[1]) - M_PI / 2.0;
+ angle = atan2f(bevp->dir[0], bevp->dir[1]) - (float)(M_PI / 2.0f);
bevp->sina = sinf(angle);
bevp->cosa = cosf(angle);
vec_to_quat(bevp->quat, bevp->dir, 5, 1);
@@ -2590,7 +2590,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
if (nu->type == CU_POLY) {
len = nu->pntsu;
bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelList2");
- if (need_seglen) {
+ if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
bl->seglen = MEM_mallocN(segcount * sizeof(float), "makeBevelList2_seglen");
bl->segbevcount = MEM_mallocN(segcount * sizeof(int), "makeBevelList2_segbevcount");
}
@@ -2613,7 +2613,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
bevp->weight = bp->weight;
bevp->split_tag = true;
bp++;
- if (seglen != NULL) {
+ if (seglen != NULL && len != 0) {
*seglen = len_v3v3(bevp->vec, bp->vec);
bevp++;
bevp->offset = *seglen;
@@ -2629,11 +2629,6 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
if ((nu->flagu & CU_NURB_CYCLIC) == 0) {
bevlist_firstlast_direction_calc_from_bpoint(nu, bl);
- if (seglen != NULL) {
- *seglen = len_v3v3(bevp->vec, nu->bp->vec);
- bl->bevpoints->offset = *seglen;
- *segbevcount = 1;
- }
}
}
else if (nu->type == CU_BEZIER) {
@@ -2641,7 +2636,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
len = segcount * resolu + 1;
bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelBPoints");
- if (need_seglen) {
+ if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
bl->seglen = MEM_mallocN(segcount * sizeof(float), "makeBevelBPoints_seglen");
bl->segbevcount = MEM_mallocN(segcount * sizeof(int), "makeBevelBPoints_segbevcount");
}
@@ -2777,7 +2772,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
len = (resolu * segcount);
bl = MEM_callocN(sizeof(BevList) + len * sizeof(BevPoint), "makeBevelList3");
- if (need_seglen) {
+ if (need_seglen && (nu->flagu & CU_NURB_CYCLIC) == 0) {
bl->seglen = MEM_mallocN(segcount * sizeof(float), "makeBevelList3_seglen");
bl->segbevcount = MEM_mallocN(segcount * sizeof(int), "makeBevelList3_segbevcount");
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index ab3cf5851e9..63eb3b397b0 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -2554,12 +2554,12 @@ void CustomData_bmesh_free_block(CustomData *data, void **block)
/**
* Same as #CustomData_bmesh_free_block but zero the memory rather then freeing.
*/
-void CustomData_bmesh_free_block_data(CustomData *data, void **block)
+void CustomData_bmesh_free_block_data(CustomData *data, void *block)
{
const LayerTypeInfo *typeInfo;
int i;
- if (*block == NULL)
+ if (block == NULL)
return;
for (i = 0; i < data->totlayer; ++i) {
@@ -2568,13 +2568,13 @@ void CustomData_bmesh_free_block_data(CustomData *data, void **block)
if (typeInfo->free) {
int offset = data->layers[i].offset;
- typeInfo->free((char *)*block + offset, 1, typeInfo->size);
+ typeInfo->free((char *)block + offset, 1, typeInfo->size);
}
}
}
if (data->totsize)
- memset(*block, 0, data->totsize);
+ memset(block, 0, data->totsize);
}
static void CustomData_bmesh_alloc_block(CustomData *data, void **block)
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 93bb4849718..44a0b93fc01 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -75,6 +75,7 @@
#include "BKE_mball.h"
#include "BKE_modifier.h"
#include "BKE_object.h"
+#include "BKE_paint.h"
#include "BKE_particle.h"
#include "BKE_pointcache.h"
#include "BKE_scene.h"
@@ -2509,6 +2510,7 @@ static void dag_id_flush_update(Main *bmain, Scene *sce, ID *id)
obt = sce->basact ? sce->basact->object : NULL;
if (obt && obt->mode & OB_MODE_TEXTURE_PAINT) {
BKE_texpaint_slots_refresh_object(sce, obt);
+ BKE_paint_proj_mesh_data_check(sce, obt, NULL, NULL, NULL, NULL);
GPU_drawobject_free(obt->derivedFinal);
}
}
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 24ee470eaa7..ced9da8d0b1 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -872,7 +872,7 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected
case PFIELD_HARMONIC:
mul_v3_fl(force, -strength * efd->falloff);
copy_v3_v3(temp, point->vel);
- mul_v3_fl(temp, -damp * 2.0f * (float)sqrt(fabs(strength)) * point->vel_to_sec);
+ mul_v3_fl(temp, -damp * 2.0f * sqrtf(fabsf(strength)) * point->vel_to_sec);
add_v3_v3(force, temp);
break;
case PFIELD_CHARGE:
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 09c1dcf701d..e90a0891436 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -55,6 +55,7 @@
#include "BKE_action.h"
#include "BKE_armature.h"
#include "BKE_constraint.h"
+#include "BKE_context.h"
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_object.h"
@@ -310,19 +311,35 @@ int list_find_data_fcurves(ListBase *dst, ListBase *src, const char *dataPrefix,
FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction **action, bool *r_driven)
{
+ return rna_get_fcurve_context_ui(NULL, ptr, prop, rnaindex, action, r_driven);
+}
+
+FCurve *rna_get_fcurve_context_ui(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int rnaindex,
+ bAction **action, bool *r_driven)
+{
FCurve *fcu = NULL;
+ PointerRNA tptr = *ptr;
*r_driven = false;
/* there must be some RNA-pointer + property combon */
- if (prop && ptr->id.data && RNA_property_animateable(ptr, prop)) {
- AnimData *adt = BKE_animdata_from_id(ptr->id.data);
- char *path;
+ if (prop && tptr.id.data && RNA_property_animateable(&tptr, prop)) {
+ AnimData *adt = BKE_animdata_from_id(tptr.id.data);
+ int step = C ? 2 : 1; /* Always 1 in case we have no context (can't check in 'ancestors' of given RNA ptr). */
+ char *path = NULL;
- if (adt) {
+ if (!adt && C) {
+ path = BKE_animdata_driver_path_hack(C, &tptr, prop, NULL);
+ adt = BKE_animdata_from_id(tptr.id.data);
+ step--;
+ }
+
+ while (adt && step--) {
if ((adt->action && adt->action->curves.first) || (adt->drivers.first)) {
/* XXX this function call can become a performance bottleneck */
- path = RNA_path_from_ID_to_property(ptr, prop);
+ if (step) {
+ path = RNA_path_from_ID_to_property(&tptr, prop);
+ }
if (path) {
/* animation takes priority over drivers */
@@ -337,13 +354,25 @@ FCurve *rna_get_fcurve(PointerRNA *ptr, PropertyRNA *prop, int rnaindex, bAction
*r_driven = true;
}
- if (fcu && action)
+ if (fcu && action) {
*action = adt->action;
-
- MEM_freeN(path);
+ break;
+ }
+ else if (step) {
+ char *tpath = BKE_animdata_driver_path_hack(C, &tptr, prop, path);
+ if (tpath && tpath != path) {
+ MEM_freeN(path);
+ path = tpath;
+ adt = BKE_animdata_from_id(tptr.id.data);
+ }
+ else {
+ adt = NULL;
+ }
+ }
}
}
}
+ MEM_SAFE_FREE(path);
}
return fcu;
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 805c1250c5d..5c673eeef3f 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -62,6 +62,7 @@
#include "DNA_meshdata_types.h"
#include "BLI_blenlib.h"
+#include "BLI_math_vector.h"
#include "BLI_threads.h"
#include "BLI_timecode.h" /* for stamp timecode format */
#include "BLI_utildefines.h"
@@ -120,12 +121,12 @@ static unsigned int imagecache_hashhash(const void *key_v)
return key->index;
}
-static int imagecache_hashcmp(const void *a_v, const void *b_v)
+static bool imagecache_hashcmp(const void *a_v, const void *b_v)
{
const ImageCacheKey *a = (ImageCacheKey *) a_v;
const ImageCacheKey *b = (ImageCacheKey *) b_v;
- return a->index - b->index;
+ return (a->index != b->index);
}
static void imagecache_keydata(void *userkey, int *framenr, int *proxy, int *render_flags)
@@ -365,6 +366,7 @@ Image *BKE_image_copy(Main *bmain, Image *ima)
nima->gen_x = ima->gen_x;
nima->gen_y = ima->gen_y;
nima->gen_type = ima->gen_type;
+ copy_v4_v4(nima->gen_color, ima->gen_color);
nima->animspeed = ima->animspeed;
@@ -769,6 +771,7 @@ Image *BKE_image_add_generated(Main *bmain, unsigned int width, unsigned int hei
ima->gen_type = gen_type;
ima->gen_flag |= (floatbuf ? IMA_GEN_FLOAT : 0);
ima->gen_depth = depth;
+ copy_v4_v4(ima->gen_color, color);
ibuf = add_ibuf_size(width, height, ima->name, depth, floatbuf, gen_type, color, &ima->colorspace_settings);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
@@ -2996,7 +2999,6 @@ BLI_INLINE bool image_quick_test(Image *ima, ImageUser *iuser)
static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
{
ImBuf *ibuf = NULL;
- float color[] = {0, 0, 0, 1};
int frame = 0, index = 0;
if (lock_r)
@@ -3041,7 +3043,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
if (ima->gen_y == 0) ima->gen_y = 1024;
if (ima->gen_depth == 0) ima->gen_depth = 24;
ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, ima->gen_depth, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type,
- color, &ima->colorspace_settings);
+ ima->gen_color, &ima->colorspace_settings);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
ima->ok = IMA_OK_LOADED;
}
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 4d80256426d..4cf9d52989f 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -1236,7 +1236,7 @@ DO_INLINE void cloth_calc_spring_force(ClothModifierData *clmd, ClothSpring *s,
sub_v3_v3v3(extent, X[s->kl], X[s->ij]);
sub_v3_v3v3(vel, V[s->kl], V[s->ij]);
dot = dot_v3v3(extent, extent);
- length = sqrt(dot);
+ length = sqrtf(dot);
s->flags &= ~CLOTH_SPRING_FLAG_NEEDED;
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 749e915e5ca..4a413850ec0 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -135,8 +135,7 @@ Lamp *localize_lamp(Lamp *la)
Lamp *lan;
int a;
- lan = BKE_libblock_copy(&la->id);
- BLI_remlink(&G.main->lamp, lan);
+ lan = BKE_libblock_copy_nolib(&la->id, false);
for (a = 0; a < MAX_MTEX; a++) {
if (lan->mtex[a]) {
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 515287de336..b49eee3ea22 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -620,6 +620,8 @@ int set_listbasepointers(Main *main, ListBase **lb)
lb[a] = NULL;
+ BLI_assert(a + 1 == MAX_LIBARRAY);
+
return a;
}
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 45695844101..5e17117a875 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -93,6 +93,7 @@ static void default_linestyle_settings(FreestyleLineStyle *linestyle)
linestyle->min_length = 0.0f;
linestyle->max_length = 10000.0f;
linestyle->split_length = 100;
+ linestyle->chain_count = 10;
linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
linestyle->integration_type = LS_INTEGRATION_MEAN;
linestyle->texstep = 1.0f;
@@ -186,6 +187,7 @@ FreestyleLineStyle *BKE_linestyle_copy(FreestyleLineStyle *linestyle)
new_linestyle->max_angle = linestyle->max_angle;
new_linestyle->min_length = linestyle->min_length;
new_linestyle->max_length = linestyle->max_length;
+ new_linestyle->chain_count = linestyle->chain_count;
new_linestyle->split_dash1 = linestyle->split_dash1;
new_linestyle->split_gap1 = linestyle->split_gap1;
new_linestyle->split_dash2 = linestyle->split_dash2;
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 1c40446c217..83ad2f1b2d2 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -1821,10 +1821,10 @@ void BKE_mask_layer_shape_unlink(MaskLayer *masklay, MaskLayerShape *masklay_sha
BKE_mask_layer_shape_free(masklay_shape);
}
-static int mask_layer_shape_sort_cb(void *masklay_shape_a_ptr, void *masklay_shape_b_ptr)
+static int mask_layer_shape_sort_cb(const void *masklay_shape_a_ptr, const void *masklay_shape_b_ptr)
{
- MaskLayerShape *masklay_shape_a = (MaskLayerShape *)masklay_shape_a_ptr;
- MaskLayerShape *masklay_shape_b = (MaskLayerShape *)masklay_shape_b_ptr;
+ const MaskLayerShape *masklay_shape_a = masklay_shape_a_ptr;
+ const MaskLayerShape *masklay_shape_b = masklay_shape_b_ptr;
if (masklay_shape_a->frame < masklay_shape_b->frame) return -1;
else if (masklay_shape_a->frame > masklay_shape_b->frame) return 1;
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 35bf453c328..e28adb7c0e0 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -406,27 +406,14 @@ static unsigned int moviecache_hashhash(const void *keyv)
return rval;
}
-static int moviecache_hashcmp(const void *av, const void *bv)
+static bool moviecache_hashcmp(const void *av, const void *bv)
{
const MovieClipImBufCacheKey *a = (MovieClipImBufCacheKey *)av;
const MovieClipImBufCacheKey *b = (MovieClipImBufCacheKey *)bv;
- if (a->framenr < b->framenr)
- return -1;
- else if (a->framenr > b->framenr)
- return 1;
-
- if (a->proxy < b->proxy)
- return -1;
- else if (a->proxy > b->proxy)
- return 1;
-
- if (a->render_flag < b->render_flag)
- return -1;
- else if (a->render_flag > b->render_flag)
- return 1;
-
- return 0;
+ return ((a->framenr != b->framenr) ||
+ (a->proxy != b->proxy) ||
+ (a->render_flag != b->render_flag));
}
static void *moviecache_getprioritydata(void *key_v)
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 0f86b551092..3a7bfb03e07 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2682,16 +2682,12 @@ static unsigned int node_instance_hash_key(const void *key)
return ((const bNodeInstanceKey *)key)->value;
}
-static int node_instance_hash_key_cmp(const void *a, const void *b)
+static bool node_instance_hash_key_cmp(const void *a, const void *b)
{
unsigned int value_a = ((const bNodeInstanceKey *)a)->value;
unsigned int value_b = ((const bNodeInstanceKey *)b)->value;
- if (value_a == value_b)
- return 0;
- else if (value_a < value_b)
- return -1;
- else
- return 1;
+
+ return (value_a != value_b);
}
bNodeInstanceHash *BKE_node_instance_hash_new(const char *info)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index b09016506e3..755ce91a8af 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1067,10 +1067,10 @@ void BKE_object_lod_add(Object *ob)
BLI_addtail(&ob->lodlevels, lod);
}
-static int lod_cmp(void *a, void *b)
+static int lod_cmp(const void *a, const void *b)
{
- LodLevel *loda = (LodLevel *)a;
- LodLevel *lodb = (LodLevel *)b;
+ const LodLevel *loda = a;
+ const LodLevel *lodb = b;
if (loda->distance < lodb->distance) return -1;
return loda->distance > lodb->distance;
@@ -3242,9 +3242,9 @@ bool BKE_boundbox_ray_hit_check(
return result;
}
-static int pc_cmp(void *a, void *b)
+static int pc_cmp(const void *a, const void *b)
{
- LinkData *ad = a, *bd = b;
+ const LinkData *ad = a, *bd = b;
if (GET_INT_FROM_POINTER(ad->data) > GET_INT_FROM_POINTER(bd->data))
return 1;
else return 0;
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 4382d74f34e..d16575d80c8 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -315,8 +315,14 @@ void BKE_paint_curve_set(Brush *br, PaintCurve *pc)
/* remove colour from palette. Must be certain color is inside the palette! */
void BKE_palette_color_remove(Palette *palette, PaletteColor *color)
{
- BLI_remlink(&palette->colors, color);
- BLI_addhead(&palette->deleted, color);
+ if (color) {
+ int numcolors = BLI_countlist(&palette->colors);
+ if ((numcolors == palette->active_color + 1) && (numcolors != 1))
+ palette->active_color--;
+
+ BLI_remlink(&palette->colors, color);
+ BLI_addhead(&palette->deleted, color);
+ }
}
void BKE_palette_cleanup(Palette *palette)
@@ -350,19 +356,6 @@ PaletteColor *BKE_palette_color_add(Palette *palette)
return color;
}
-void BKE_palette_color_delete(struct Palette *palette)
-{
- PaletteColor *color = BLI_findlink(&palette->colors, palette->active_color);
-
- if (color) {
- if ((color == palette->colors.last) && (palette->colors.last != palette->colors.first))
- palette->active_color--;
-
- BLI_remlink(&palette->colors, color);
- BLI_addhead(&palette->deleted, color);
- }
-}
-
bool BKE_palette_is_empty(const struct Palette *palette)
{
@@ -493,7 +486,7 @@ void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, const float mouse_
sub_v2_v2v2(dpos, ups->last_rake, mouse_pos);
if (len_squared_v2(dpos) >= r * r) {
- ups->brush_rotation = atan2(dpos[0], dpos[1]);
+ ups->brush_rotation = atan2f(dpos[0], dpos[1]);
interp_v2_v2v2(ups->last_rake, ups->last_rake,
mouse_pos, u);
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 27d346f65b9..530573d6e38 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -656,7 +656,7 @@ static float psys_render_projected_area(ParticleSystem *psys, const float center
}
/* screen space radius */
- radius = sqrt(area / (float)M_PI);
+ radius = sqrtf(area / (float)M_PI);
/* make smaller using fallof once over screen edge */
*viewport = 1.0f;
@@ -917,8 +917,8 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
elem->scalemax = (lambda + t < 1.0f) ? 1.0f / lambda : 1.0f / (1.0f - elem->t * elem->t / t);
elem->scalemin = (lambda + t < 1.0f) ? 0.0f : elem->scalemax * (1.0f - elem->t / t);
- elem->scalemin = sqrt(elem->scalemin);
- elem->scalemax = sqrt(elem->scalemax);
+ elem->scalemin = sqrtf(elem->scalemin);
+ elem->scalemax = sqrtf(elem->scalemax);
/* clamp scaling */
scaleclamp = (float)min_ii(elem->totchild, 10);
@@ -939,8 +939,8 @@ int psys_render_simplify_distribution(ParticleThreadContext *ctx, int tot)
}
elem->lambda = lambda;
- elem->scalemin = sqrt(elem->scalemin);
- elem->scalemax = sqrt(elem->scalemax);
+ elem->scalemin = sqrtf(elem->scalemin);
+ elem->scalemax = sqrtf(elem->scalemax);
elem->curchild = 0;
}
@@ -1950,10 +1950,10 @@ static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float
t = time * freq * (float)M_PI;
if (smooth_start) {
- dt = fabs(t);
+ dt = fabsf(t);
/* smooth the beginning of kink */
CLAMP(dt, 0.f, (float)M_PI);
- dt = sin(dt / 2.f);
+ dt = sinf(dt / 2.f);
}
if (type != PART_KINK_RADIAL) {
@@ -2014,12 +2014,12 @@ static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float
madd_v3_v3fl(result, proj, flat);
}
- madd_v3_v3fl(result, par_vec, -amplitude * (float)sin(t));
+ madd_v3_v3fl(result, par_vec, -amplitude * sinf(t));
break;
}
case PART_KINK_WAVE:
{
- madd_v3_v3fl(result, kink, amplitude * (float)sin(t));
+ madd_v3_v3fl(result, kink, amplitude * sinf(t));
if (flat > 0.f) {
float proj[3];
@@ -2054,22 +2054,22 @@ static void do_kink(ParticleKey *state, ParticleKey *par, float *par_rot, float
if (inp_y > 0.5f) {
copy_v3_v3(state_co, y_vec);
- mul_v3_fl(y_vec, amplitude * (float)cos(t));
- mul_v3_fl(z_vec, amplitude / 2.f * (float)sin(2.f * t));
+ mul_v3_fl(y_vec, amplitude * cosf(t));
+ mul_v3_fl(z_vec, amplitude / 2.f * sinf(2.f * t));
}
else if (inp_z > 0.0f) {
- mul_v3_v3fl(state_co, z_vec, (float)sin((float)M_PI / 3.f));
+ mul_v3_v3fl(state_co, z_vec, sinf((float)M_PI / 3.f));
madd_v3_v3fl(state_co, y_vec, -0.5f);
- mul_v3_fl(y_vec, -amplitude * (float)cos(t + (float)M_PI / 3.f));
- mul_v3_fl(z_vec, amplitude / 2.f * (float)cos(2.f * t + (float)M_PI / 6.f));
+ mul_v3_fl(y_vec, -amplitude * cosf(t + (float)M_PI / 3.f));
+ mul_v3_fl(z_vec, amplitude / 2.f * cosf(2.f * t + (float)M_PI / 6.f));
}
else {
- mul_v3_v3fl(state_co, z_vec, -(float)sin((float)M_PI / 3.f));
+ mul_v3_v3fl(state_co, z_vec, -sinf((float)M_PI / 3.f));
madd_v3_v3fl(state_co, y_vec, -0.5f);
- mul_v3_fl(y_vec, amplitude * (float)-sin(t + (float)M_PI / 6.f));
- mul_v3_fl(z_vec, amplitude / 2.f * (float)-sin(2.f * t + (float)M_PI / 3.f));
+ mul_v3_fl(y_vec, amplitude * -sinf(t + (float)M_PI / 6.f));
+ mul_v3_fl(z_vec, amplitude / 2.f * -sinf(2.f * t + (float)M_PI / 3.f));
}
mul_v3_fl(state_co, amplitude);
@@ -2271,8 +2271,11 @@ static void do_rough(float *loc, float mat[4][4], float t, float fac, float size
float rough[3];
float rco[3];
- if (thres != 0.0f)
- if ((float)fabs((float)(-1.5f + loc[0] + loc[1] + loc[2])) < 1.5f * thres) return;
+ if (thres != 0.0f) {
+ if (fabsf((float)(-1.5f + loc[0] + loc[1] + loc[2])) < 1.5f * thres) {
+ return;
+ }
+ }
copy_v3_v3(rco, loc);
mul_v3_fl(rco, t);
@@ -4567,8 +4570,8 @@ void psys_get_dupli_path_transform(ParticleSimulationData *sim, ParticleData *pa
normalize_v3(nor);
/* make sure that we get a proper side vector */
- if (fabs(dot_v3v3(nor, vec)) > 0.999999) {
- if (fabs(dot_v3v3(nor, xvec)) > 0.999999) {
+ if (fabsf(dot_v3v3(nor, vec)) > 0.999999) {
+ if (fabsf(dot_v3v3(nor, xvec)) > 0.999999) {
nor[0] = 0.0f;
nor[1] = 1.0f;
nor[2] = 0.0f;
@@ -4676,12 +4679,12 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3]
copy_v3_v3(tvec, xvec);
copy_v3_v3(tvec2, yvec);
- mul_v3_fl(xvec, cos(bb->tilt * (float)M_PI));
- mul_v3_fl(tvec2, sin(bb->tilt * (float)M_PI));
+ mul_v3_fl(xvec, cosf(bb->tilt * (float)M_PI));
+ mul_v3_fl(tvec2, sinf(bb->tilt * (float)M_PI));
add_v3_v3(xvec, tvec2);
- mul_v3_fl(yvec, cos(bb->tilt * (float)M_PI));
- mul_v3_fl(tvec, -sin(bb->tilt * (float)M_PI));
+ mul_v3_fl(yvec, cosf(bb->tilt * (float)M_PI));
+ mul_v3_fl(tvec, -sinf(bb->tilt * (float)M_PI));
add_v3_v3(yvec, tvec);
mul_v3_fl(xvec, bb->size[0]);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 09e20c02691..155299b69c3 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -701,7 +701,7 @@ static void init_mv_jit(float *jit, int num, int seed2, float amount)
rad1= (float)(1.0f/sqrtf((float)num));
rad2= (float)(1.0f/((float)num));
- rad3= (float)sqrt((float)num)/((float)num);
+ rad3= (float)sqrtf((float)num)/((float)num);
rng = BLI_rng_new(31415926 + num + seed2);
x= 0;
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index 55653f41e75..1a0ddac03d7 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -823,15 +823,16 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, PBVH *bvh,
return any_subdivided;
}
-static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e,
- BMVert *v1, BMVert *v2,
- GSet *deleted_verts,
- BLI_Buffer *edge_loops,
- BLI_Buffer *deleted_faces,
- EdgeQueueContext *eq_ctx)
+static void pbvh_bmesh_collapse_edge(
+ PBVH *bvh, BMEdge *e,
+ BMVert *v1, BMVert *v2,
+ GSet *deleted_verts,
+ BLI_Buffer *deleted_faces,
+ EdgeQueueContext *eq_ctx)
{
BMIter bm_iter;
BMFace *f;
+ BMLoop *l_adj;
BMVert *v_del, *v_conn;
int i;
float mask_v1 = BM_ELEM_CD_GET_FLOAT(v1, eq_ctx->cd_vert_mask_offset);
@@ -846,15 +847,11 @@ static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e,
v_conn = v1;
}
- /* Get all faces adjacent to the edge */
- pbvh_bmesh_edge_loops(edge_loops, e);
-
/* Remove the merge vertex from the PBVH */
pbvh_bmesh_vert_remove(bvh, v_del, eq_ctx->cd_vert_node_offset, eq_ctx->cd_face_node_offset);
/* Remove all faces adjacent to the edge */
- for (i = 0; i < edge_loops->count; i++) {
- BMLoop *l_adj = BLI_buffer_at(edge_loops, BMLoop *, i);
+ while ((l_adj = e->l)) {
BMFace *f_adj = l_adj->f;
pbvh_bmesh_face_remove(bvh, f_adj, eq_ctx->cd_vert_node_offset, eq_ctx->cd_face_node_offset);
@@ -973,10 +970,10 @@ static void pbvh_bmesh_collapse_edge(PBVH *bvh, BMEdge *e,
BM_vert_kill(bvh->bm, v_del);
}
-static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
- PBVH *bvh,
- BLI_Buffer *edge_loops,
- BLI_Buffer *deleted_faces)
+static bool pbvh_bmesh_collapse_short_edges(
+ EdgeQueueContext *eq_ctx,
+ PBVH *bvh,
+ BLI_Buffer *deleted_faces)
{
float min_len_squared = bvh->bm_min_edge_len * bvh->bm_min_edge_len;
GSet *deleted_verts;
@@ -1020,7 +1017,7 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx,
any_collapsed = true;
pbvh_bmesh_collapse_edge(bvh, e, v1, v2,
- deleted_verts, edge_loops,
+ deleted_verts,
deleted_faces, eq_ctx);
}
@@ -1214,7 +1211,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
const float center[3], float radius)
{
/* 2 is enough for edge faces - manifold edge */
- BLI_buffer_declare_static(BMFace *, edge_loops, BLI_BUFFER_NOP, 2);
+ BLI_buffer_declare_static(BMLoop *, edge_loops, BLI_BUFFER_NOP, 2);
BLI_buffer_declare_static(BMFace *, deleted_faces, BLI_BUFFER_NOP, 32);
const int cd_vert_mask_offset = CustomData_get_offset(&bvh->bm->vdata, CD_PAINT_MASK);
const int cd_vert_node_offset = bvh->cd_vert_node_offset;
@@ -1230,7 +1227,7 @@ bool BKE_pbvh_bmesh_update_topology(PBVH *bvh, PBVHTopologyUpdateMode mode,
short_edge_queue_create(&eq_ctx, bvh, center, radius);
modified |= !BLI_heap_is_empty(q.heap);
- pbvh_bmesh_collapse_short_edges(&eq_ctx, bvh, &edge_loops,
+ pbvh_bmesh_collapse_short_edges(&eq_ctx, bvh,
&deleted_faces);
BLI_heap_free(q.heap, NULL);
BLI_mempool_destroy(queue_pool);
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 063a81e6efb..a6a7664ec61 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -85,11 +85,12 @@
#ifdef WITH_LZO
#include "minilzo.h"
-#else
-/* used for non-lzo cases */
-#define LZO_OUT_LEN(size) ((size) + (size) / 16 + 64 + 3)
+#define LZO_HEAP_ALLOC(var,size) \
+ lzo_align_t __LZO_MMODEL var [ ((size) + (sizeof(lzo_align_t) - 1)) / sizeof(lzo_align_t) ]
#endif
+#define LZO_OUT_LEN(size) ((size) + (size) / 16 + 64 + 3)
+
#ifdef WITH_LZMA
#include "LzmaLib.h"
#endif
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index eb98e381222..5bfd6e8a120 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -93,9 +93,6 @@
#include "bmesh.h"
-//XXX #include "BIF_previewrender.h"
-//XXX #include "BIF_editseq.h"
-
#ifdef WIN32
#else
# include <sys/time.h>
@@ -521,6 +518,9 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
sce->r.preview_start_resolution = 64;
+ sce->r.line_thickness_mode = R_LINE_THICKNESS_ABSOLUTE;
+ sce->r.unit_line_thickness = 1.0f;
+
sce->toolsettings = MEM_callocN(sizeof(struct ToolSettings), "Tool Settings Struct");
sce->toolsettings->doublimit = 0.001;
sce->toolsettings->uvcalc_margin = 0.001f;
@@ -1991,14 +1991,13 @@ double BKE_scene_unit_scale(const UnitSettings *unit, const int unit_type, doubl
switch (unit_type) {
case B_UNIT_LENGTH:
return value * (double)unit->scale_length;
- case B_UNIT_CAMERA:
- return value * (double)unit->scale_length;
case B_UNIT_AREA:
return value * pow(unit->scale_length, 2);
case B_UNIT_VOLUME:
return value * pow(unit->scale_length, 3);
case B_UNIT_MASS:
return value * pow(unit->scale_length, 3);
+ case B_UNIT_CAMERA: /* *Do not* use scene's unit scale for camera focal lens! See T42026. */
default:
return value;
}
diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c
index 97062f728c5..4268b33cb14 100644
--- a/source/blender/blenkernel/intern/seqcache.c
+++ b/source/blender/blenkernel/intern/seqcache.c
@@ -69,58 +69,15 @@ static struct SeqPreprocessCache *preprocess_cache = NULL;
static void preprocessed_cache_destruct(void);
-static int seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
+static bool seq_cmp_render_data(const SeqRenderData *a, const SeqRenderData *b)
{
- if (a->preview_render_size < b->preview_render_size) {
- return -1;
- }
- if (a->preview_render_size > b->preview_render_size) {
- return 1;
- }
-
- if (a->rectx < b->rectx) {
- return -1;
- }
- if (a->rectx > b->rectx) {
- return 1;
- }
-
- if (a->recty < b->recty) {
- return -1;
- }
- if (a->recty > b->recty) {
- return 1;
- }
-
- if (a->bmain < b->bmain) {
- return -1;
- }
- if (a->bmain > b->bmain) {
- return 1;
- }
-
- if (a->scene < b->scene) {
- return -1;
- }
- if (a->scene > b->scene) {
- return 1;
- }
-
- if (a->motion_blur_shutter < b->motion_blur_shutter) {
- return -1;
- }
- if (a->motion_blur_shutter > b->motion_blur_shutter) {
- return 1;
- }
-
- if (a->motion_blur_samples < b->motion_blur_samples) {
- return -1;
- }
- if (a->motion_blur_samples > b->motion_blur_samples) {
- return 1;
- }
-
- return 0;
+ return ((a->preview_render_size != b->preview_render_size) ||
+ (a->rectx != b->rectx) ||
+ (a->recty != b->recty) ||
+ (a->bmain != b->bmain) ||
+ (a->scene != b->scene) ||
+ (a->motion_blur_shutter != b->motion_blur_shutter) ||
+ (a->motion_blur_samples != b->motion_blur_samples));
}
static unsigned int seq_hash_render_data(const SeqRenderData *a)
@@ -148,33 +105,15 @@ static unsigned int seqcache_hashhash(const void *key_)
return rval;
}
-static int seqcache_hashcmp(const void *a_, const void *b_)
+static bool seqcache_hashcmp(const void *a_, const void *b_)
{
const SeqCacheKey *a = (SeqCacheKey *) a_;
const SeqCacheKey *b = (SeqCacheKey *) b_;
- if (a->seq < b->seq) {
- return -1;
- }
- if (a->seq > b->seq) {
- return 1;
- }
-
- if (a->cfra < b->cfra) {
- return -1;
- }
- if (a->cfra > b->cfra) {
- return 1;
- }
-
- if (a->type < b->type) {
- return -1;
- }
- if (a->type > b->type) {
- return 1;
- }
-
- return seq_cmp_render_data(&a->context, &b->context);
+ return ((a->seq != b->seq) ||
+ (a->cfra != b->cfra) ||
+ (a->type != b->type) ||
+ seq_cmp_render_data(&a->context, &b->context));
}
void BKE_sequencer_cache_destruct(void)
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index a8e578eae0d..11a6cb7acc3 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -1322,7 +1322,7 @@ static float check_zone(WipeZone *wipezone, int x, int y, Sequence *seq, float f
if (angle == 0.0f) {
b1 = posy;
b2 = y;
- hyp = fabs(y - posy);
+ hyp = fabsf(y - posy);
}
else {
b1 = posy - (-angle) * posx;
@@ -1745,8 +1745,8 @@ static void transform_image(int x, int y, ImBuf *ibuf1, ImBuf *out, float scale
yo = y;
/* Rotate */
- s = sin(rotate);
- c = cos(rotate);
+ s = sinf(rotate);
+ c = cosf(rotate);
for (yi = 0; yi < yo; yi++) {
for (xi = 0; xi < xo; xi++) {
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 9c411142566..13575560669 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -2160,7 +2160,7 @@ static void sb_spring_force(Object *ob, int bpi, BodySpring *bs, float iks, floa
// dfdx_spring(ia, ia, op, dir, bs->len, distance, -mpos);
/* depending on my vel */
// dfdv_goal(ia, ia, mvel); // well that ignores geometie
- if (bp2->goal < SOFTGOALSNAP) { /* ommit this bp when it snaps */
+ if (bp2->goal < SOFTGOALSNAP) { /* omit this bp when it snaps */
/* depending on other pos */
// dfdx_spring(ia, ic, op, dir, bs->len, distance, mpos);
/* depending on other vel */
@@ -2257,7 +2257,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
}
/* naive ball self collision done */
- if (_final_goal(ob, bp) < SOFTGOALSNAP) { /* ommit this bp when it snaps */
+ if (_final_goal(ob, bp) < SOFTGOALSNAP) { /* omit this bp when it snaps */
float auxvect[3];
float velgoal[3];
@@ -2652,7 +2652,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
}
/* naive ball self collision done */
- if (_final_goal(ob, bp) < SOFTGOALSNAP) { /* ommit this bp when it snaps */
+ if (_final_goal(ob, bp) < SOFTGOALSNAP) { /* omit this bp when it snaps */
float auxvect[3];
float velgoal[3];
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 4cd85fb342e..8a272cd9d81 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -267,16 +267,79 @@ static void cleanup_textline(TextLine *tl)
tl->len += txt_extended_ascii_as_utf8(&tl->line);
}
+/**
+ * used for load and reload (unlike txt_insert_buf)
+ * assumes all fields are empty
+ */
+static void text_from_buf(Text *text, const unsigned char *buffer, const int len)
+{
+ int i, llen;
+
+ BLI_assert(BLI_listbase_is_empty(&text->lines));
+
+ text->nlines = 0;
+ llen = 0;
+ for (i = 0; i < len; i++) {
+ if (buffer[i] == '\n') {
+ TextLine *tmp;
+
+ tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
+ tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string");
+ tmp->format = NULL;
+
+ if (llen) memcpy(tmp->line, &buffer[i - llen], llen);
+ tmp->line[llen] = 0;
+ tmp->len = llen;
+
+ cleanup_textline(tmp);
+
+ BLI_addtail(&text->lines, tmp);
+ text->nlines++;
+
+ llen = 0;
+ continue;
+ }
+ llen++;
+ }
+
+ /* create new line in cases:
+ * - rest of line (if last line in file hasn't got \n terminator).
+ * in this case content of such line would be used to fill text line buffer
+ * - file is empty. in this case new line is needed to start editing from.
+ * - last characted in buffer is \n. in this case new line is needed to
+ * deal with newline at end of file. (see [#28087]) (sergey) */
+ if (llen != 0 || text->nlines == 0 || buffer[len - 1] == '\n') {
+ TextLine *tmp;
+
+ tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
+ tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string");
+ tmp->format = NULL;
+
+ if (llen) memcpy(tmp->line, &buffer[i - llen], llen);
+
+ tmp->line[llen] = 0;
+ tmp->len = llen;
+
+ cleanup_textline(tmp);
+
+ BLI_addtail(&text->lines, tmp);
+ text->nlines++;
+ }
+
+ text->curl = text->sell = text->lines.first;
+ text->curc = text->selc = 0;
+}
+
int BKE_text_reload(Text *text)
{
FILE *fp;
- int i, llen, len;
+ int len;
unsigned char *buffer;
TextLine *tmp;
char str[FILE_MAX];
- struct stat st;
+ BLI_stat_t st;
- if (!text || !text->name) return 0;
+ if (!text->name) return 0;
BLI_strncpy(str, text->name, FILE_MAX);
BLI_path_abs(str, G.main->name);
@@ -299,13 +362,12 @@ int BKE_text_reload(Text *text)
/* clear undo buffer */
MEM_freeN(text->undo_buf);
init_undo_text(text);
-
+
fseek(fp, 0L, SEEK_END);
len = ftell(fp);
fseek(fp, 0L, SEEK_SET);
- text->undo_pos = -1;
-
+
buffer = MEM_mallocN(len, "text_buffer");
// under windows fread can return less then len bytes because
// of CR stripping
@@ -313,51 +375,11 @@ int BKE_text_reload(Text *text)
fclose(fp);
- stat(str, &st);
+ BLI_stat(str, &st);
text->mtime = st.st_mtime;
-
- text->nlines = 0;
- llen = 0;
- for (i = 0; i < len; i++) {
- if (buffer[i] == '\n') {
- tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
- tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string");
- tmp->format = NULL;
-
- if (llen) memcpy(tmp->line, &buffer[i - llen], llen);
- tmp->line[llen] = 0;
- tmp->len = llen;
-
- cleanup_textline(tmp);
- BLI_addtail(&text->lines, tmp);
- text->nlines++;
-
- llen = 0;
- continue;
- }
- llen++;
- }
+ text_from_buf(text, buffer, len);
- if (llen != 0 || text->nlines == 0) {
- tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
- tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string");
- tmp->format = NULL;
-
- if (llen) memcpy(tmp->line, &buffer[i - llen], llen);
-
- tmp->line[llen] = 0;
- tmp->len = llen;
-
- cleanup_textline(tmp);
-
- BLI_addtail(&text->lines, tmp);
- text->nlines++;
- }
-
- text->curl = text->sell = text->lines.first;
- text->curc = text->selc = 0;
-
MEM_freeN(buffer);
return 1;
}
@@ -365,12 +387,11 @@ int BKE_text_reload(Text *text)
Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const bool is_internal)
{
FILE *fp;
- int i, llen, len;
+ int len;
unsigned char *buffer;
- TextLine *tmp;
Text *ta;
char str[FILE_MAX];
- struct stat st;
+ BLI_stat_t st;
BLI_strncpy(str, file, FILE_MAX);
if (relpath) /* can be NULL (bg mode) */
@@ -388,10 +409,6 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const
if ((U.flag & USER_TXT_TABSTOSPACES_DISABLE) == 0)
ta->flags = TXT_TABSTOSPACES;
- fseek(fp, 0L, SEEK_END);
- len = ftell(fp);
- fseek(fp, 0L, SEEK_SET);
-
if (is_internal == false) {
ta->name = MEM_mallocN(strlen(file) + 1, "text_name");
strcpy(ta->name, file);
@@ -400,7 +417,12 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const
ta->flags |= TXT_ISMEM | TXT_ISDIRTY;
}
+ /* clear undo buffer */
init_undo_text(ta);
+
+ fseek(fp, 0L, SEEK_END);
+ len = ftell(fp);
+ fseek(fp, 0L, SEEK_SET);
buffer = MEM_mallocN(len, "text_buffer");
// under windows fread can return less then len bytes because
@@ -409,56 +431,10 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const
fclose(fp);
- stat(str, &st);
+ BLI_stat(str, &st);
ta->mtime = st.st_mtime;
- ta->nlines = 0;
- llen = 0;
- for (i = 0; i < len; i++) {
- if (buffer[i] == '\n') {
- tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
- tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string");
- tmp->format = NULL;
-
- if (llen) memcpy(tmp->line, &buffer[i - llen], llen);
- tmp->line[llen] = 0;
- tmp->len = llen;
-
- cleanup_textline(tmp);
-
- BLI_addtail(&ta->lines, tmp);
- ta->nlines++;
-
- llen = 0;
- continue;
- }
- llen++;
- }
-
- /* create new line in cases:
- * - rest of line (if last line in file hasn't got \n terminator).
- * in this case content of such line would be used to fill text line buffer
- * - file is empty. in this case new line is needed to start editing from.
- * - last characted in buffer is \n. in this case new line is needed to
- * deal with newline at end of file. (see [#28087]) (sergey) */
- if (llen != 0 || ta->nlines == 0 || buffer[len - 1] == '\n') {
- tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
- tmp->line = (char *) MEM_mallocN(llen + 1, "textline_string");
- tmp->format = NULL;
-
- if (llen) memcpy(tmp->line, &buffer[i - llen], llen);
-
- tmp->line[llen] = 0;
- tmp->len = llen;
-
- cleanup_textline(tmp);
-
- BLI_addtail(&ta->lines, tmp);
- ta->nlines++;
- }
-
- ta->curl = ta->sell = ta->lines.first;
- ta->curc = ta->selc = 0;
+ text_from_buf(ta, buffer, len);
MEM_freeN(buffer);
@@ -671,7 +647,7 @@ int BKE_text_file_modified_check(Text *text)
int result;
char file[FILE_MAX];
- if (!text || !text->name)
+ if (!text->name)
return 0;
BLI_strncpy(file, text->name, FILE_MAX);
@@ -700,7 +676,7 @@ void BKE_text_file_modified_ignore(Text *text)
int result;
char file[FILE_MAX];
- if (!text || !text->name) return;
+ if (!text->name) return;
BLI_strncpy(file, text->name, FILE_MAX);
BLI_path_abs(file, G.main->name);
@@ -766,9 +742,7 @@ static TextLine *txt_new_linen(const char *str, int n)
void txt_clean_text(Text *text)
{
TextLine **top, **bot;
-
- if (!text) return;
-
+
if (!text->lines.first) {
if (text->lines.last) text->lines.first = text->lines.last;
else text->lines.first = text->lines.last = txt_new_line(NULL);
@@ -907,8 +881,7 @@ void txt_move_up(Text *text, const bool sel)
{
TextLine **linep;
int *charp;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
@@ -930,8 +903,7 @@ void txt_move_down(Text *text, const bool sel)
{
TextLine **linep;
int *charp;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
@@ -953,8 +925,7 @@ void txt_move_left(Text *text, const bool sel)
TextLine **linep;
int *charp;
int tabsize = 0, i = 0;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
@@ -998,8 +969,7 @@ void txt_move_right(Text *text, const bool sel)
TextLine **linep;
int *charp, i;
bool do_tab = false;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
@@ -1040,8 +1010,7 @@ void txt_jump_left(Text *text, const bool sel, const bool use_init_step)
{
TextLine **linep;
int *charp;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
@@ -1057,8 +1026,7 @@ void txt_jump_right(Text *text, const bool sel, const bool use_init_step)
{
TextLine **linep;
int *charp;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
@@ -1074,8 +1042,7 @@ void txt_move_bol(Text *text, const bool sel)
{
TextLine **linep;
int *charp;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
@@ -1089,8 +1056,7 @@ void txt_move_eol(Text *text, const bool sel)
{
TextLine **linep;
int *charp;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
@@ -1104,8 +1070,7 @@ void txt_move_bof(Text *text, const bool sel)
{
TextLine **linep;
int *charp;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
@@ -1120,8 +1085,7 @@ void txt_move_eof(Text *text, const bool sel)
{
TextLine **linep;
int *charp;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
@@ -1143,8 +1107,7 @@ void txt_move_to(Text *text, unsigned int line, unsigned int ch, const bool sel)
TextLine **linep;
int *charp;
unsigned int i;
-
- if (!text) return;
+
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
@@ -1181,7 +1144,6 @@ static void txt_curs_swap(Text *text)
static void txt_pop_first(Text *text)
{
-
if (txt_get_span(text->curl, text->sell) < 0 ||
(text->curl == text->sell && text->curc > text->selc))
{
@@ -1210,7 +1172,6 @@ void txt_pop_sel(Text *text)
void txt_order_cursors(Text *text, const bool reverse)
{
- if (!text) return;
if (!text->curl) return;
if (!text->sell) return;
@@ -1240,8 +1201,7 @@ static void txt_delete_sel(Text *text)
{
TextLine *tmpl;
char *buf;
-
- if (!text) return;
+
if (!text->curl) return;
if (!text->sell) return;
@@ -1277,8 +1237,6 @@ static void txt_delete_sel(Text *text)
void txt_sel_all(Text *text)
{
- if (!text) return;
-
text->curl = text->lines.first;
text->curc = 0;
@@ -1301,7 +1259,6 @@ void txt_sel_clear(Text *text)
void txt_sel_line(Text *text)
{
- if (!text) return;
if (!text->curl) return;
text->curc = 0;
@@ -1319,8 +1276,7 @@ char *txt_to_buf(Text *text)
TextLine *tmp, *linef, *linel;
int charf, charl;
char *buf;
-
- if (!text) return NULL;
+
if (!text->curl) return NULL;
if (!text->sell) return NULL;
if (!text->lines.first) return NULL;
@@ -1382,7 +1338,7 @@ int txt_find_string(Text *text, const char *findstr, int wrap, int match_case)
TextLine *tl, *startl;
const char *s = NULL;
- if (!text || !text->curl || !text->sell) return 0;
+ if (!text->curl || !text->sell) return 0;
txt_order_cursors(text, false);
@@ -1422,8 +1378,7 @@ char *txt_sel_to_buf(Text *text)
int length = 0;
TextLine *tmp, *linef, *linel;
int charf, charl;
-
- if (!text) return NULL;
+
if (!text->curl) return NULL;
if (!text->sell) return NULL;
@@ -1504,7 +1459,6 @@ void txt_insert_buf(Text *text, const char *in_buffer)
TextLine *add;
char *buffer;
- if (!text) return;
if (!in_buffer) return;
txt_delete_sel(text);
@@ -2386,8 +2340,7 @@ void txt_split_curline(Text *text)
{
TextLine *ins;
char *left, *right;
-
- if (!text) return;
+
if (!text->curl) return;
txt_delete_sel(text);
@@ -2429,7 +2382,6 @@ void txt_split_curline(Text *text)
static void txt_delete_line(Text *text, TextLine *line)
{
- if (!text) return;
if (!text->curl) return;
BLI_remlink(&text->lines, line);
@@ -2446,8 +2398,6 @@ static void txt_delete_line(Text *text, TextLine *line)
static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb)
{
char *tmp, *s;
-
- if (!text) return;
if (!linea || !lineb) return;
@@ -2471,7 +2421,7 @@ void txt_duplicate_line(Text *text)
{
TextLine *textline;
- if (!text || !text->curl) return;
+ if (!text->curl) return;
if (text->curl == text->sell) {
textline = txt_new_line(text->curl->line);
@@ -2487,8 +2437,7 @@ void txt_duplicate_line(Text *text)
void txt_delete_char(Text *text)
{
unsigned int c = '\n';
-
- if (!text) return;
+
if (!text->curl) return;
if (txt_has_sel(text)) { /* deleting a selection */
@@ -2531,7 +2480,6 @@ void txt_backspace_char(Text *text)
{
unsigned int c = '\n';
- if (!text) return;
if (!text->curl) return;
if (txt_has_sel(text)) { /* deleting a selection */
@@ -2595,8 +2543,7 @@ static bool txt_add_char_intern(Text *text, unsigned int add, bool replace_tabs)
{
char *tmp, ch[BLI_UTF8_MAX];
size_t add_len;
-
- if (!text) return 0;
+
if (!text->curl) return 0;
if (add == '\n') {
@@ -2655,8 +2602,7 @@ bool txt_replace_char(Text *text, unsigned int add)
unsigned int del;
size_t del_size = 0, add_size;
char ch[BLI_UTF8_MAX];
-
- if (!text) return 0;
+
if (!text->curl) return 0;
/* If text is selected or we're at the end of the line just use txt_add_char */
@@ -2710,7 +2656,7 @@ void txt_indent(Text *text)
/* hardcoded: TXT_TABSIZE = 4 spaces: */
int spaceslen = TXT_TABSIZE;
- if (ELEM(NULL, text, text->curl, text->sell)) {
+ if (ELEM(NULL, text->curl, text->sell)) {
return;
}
@@ -2777,7 +2723,7 @@ void txt_unindent(Text *text)
/* hardcoded: TXT_TABSIZE = 4 spaces: */
int spaceslen = TXT_TABSIZE;
- if (ELEM(NULL, text, text->curl, text->sell)) {
+ if (ELEM(NULL, text->curl, text->sell)) {
return;
}
@@ -2830,8 +2776,7 @@ void txt_comment(Text *text)
int len, num;
char *tmp;
char add = '#';
-
- if (!text) return;
+
if (!text->curl) return;
if (!text->sell) return; // Need to change this need to check if only one line is selected to more than one
@@ -2878,8 +2823,7 @@ void txt_uncomment(Text *text)
{
int num = 0;
char remove = '#';
-
- if (!text) return;
+
if (!text->curl) return;
if (!text->sell) return;
@@ -2925,7 +2869,7 @@ void txt_move_lines(struct Text *text, const int direction)
BLI_assert(ELEM(direction, TXT_MOVE_LINE_UP, TXT_MOVE_LINE_DOWN));
- if (!text || !text->curl || !text->sell) return;
+ if (!text->curl || !text->sell) return;
txt_order_cursors(text, false);
@@ -2958,6 +2902,7 @@ int txt_setcurr_tab_spaces(Text *text, int space)
const char *comm = "#";
const char indent = (text->flags & TXT_TABSTOSPACES) ? ' ' : '\t';
static const char *back_words[] = {"return", "break", "continue", "pass", "yield", NULL};
+
if (!text->curl) return 0;
while (text->curl->line[i] == indent) {
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index b77cd744a18..40d9dc0d7e0 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -371,6 +371,9 @@ void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingO
while (track) {
MovieTrackingTrack *new_track = BKE_tracking_track_duplicate(track);
+ if (track->prev == NULL) {
+ tracking->act_track = new_track;
+ }
BLI_addtail(tracksbase, new_track);
BKE_tracking_track_unique_name(tracksbase, new_track);
@@ -1789,13 +1792,19 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *
if (ibuf->rect_float) {
if (undistort) {
libmv_cameraIntrinsicsUndistortFloat(distortion->intrinsics,
- ibuf->rect_float, resibuf->rect_float,
- ibuf->x, ibuf->y, overscan, ibuf->channels);
+ ibuf->rect_float,
+ ibuf->x, ibuf->y,
+ overscan,
+ ibuf->channels,
+ resibuf->rect_float);
}
else {
libmv_cameraIntrinsicsDistortFloat(distortion->intrinsics,
- ibuf->rect_float, resibuf->rect_float,
- ibuf->x, ibuf->y, overscan, ibuf->channels);
+ ibuf->rect_float,
+ ibuf->x, ibuf->y,
+ overscan,
+ ibuf->channels,
+ resibuf->rect_float);
}
if (ibuf->rect)
@@ -1804,13 +1813,19 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *
else {
if (undistort) {
libmv_cameraIntrinsicsUndistortByte(distortion->intrinsics,
- (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
- ibuf->x, ibuf->y, overscan, ibuf->channels);
+ (unsigned char *)ibuf->rect,
+ ibuf->x, ibuf->y,
+ overscan,
+ ibuf->channels,
+ (unsigned char *)resibuf->rect);
}
else {
libmv_cameraIntrinsicsDistortByte(distortion->intrinsics,
- (unsigned char *)ibuf->rect, (unsigned char *)resibuf->rect,
- ibuf->x, ibuf->y, overscan, ibuf->channels);
+ (unsigned char *)ibuf->rect,
+ ibuf->x, ibuf->y,
+ overscan,
+ ibuf->channels,
+ (unsigned char *)resibuf->rect);
}
}
@@ -2017,14 +2032,14 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
}
if (search_ibuf->rect_float) {
- libmv_samplePlanarPatch(search_ibuf->rect_float,
- search_ibuf->x, search_ibuf->y, 4,
- src_pixel_x, src_pixel_y,
- num_samples_x, num_samples_y,
- mask,
- pattern_ibuf->rect_float,
- &warped_position_x,
- &warped_position_y);
+ libmv_samplePlanarPatchFloat(search_ibuf->rect_float,
+ search_ibuf->x, search_ibuf->y, 4,
+ src_pixel_x, src_pixel_y,
+ num_samples_x, num_samples_y,
+ mask,
+ pattern_ibuf->rect_float,
+ &warped_position_x,
+ &warped_position_y);
}
else {
libmv_samplePlanarPatchByte((unsigned char *) search_ibuf->rect,
@@ -2185,10 +2200,10 @@ void BKE_tracking_disable_channels(ImBuf *ibuf, bool disable_red, bool disable_g
/* ** Channels sort comparators ** */
-static int channels_alpha_sort(void *a, void *b)
+static int channels_alpha_sort(const void *a, const void *b)
{
- MovieTrackingDopesheetChannel *channel_a = a;
- MovieTrackingDopesheetChannel *channel_b = b;
+ const MovieTrackingDopesheetChannel *channel_a = a;
+ const MovieTrackingDopesheetChannel *channel_b = b;
if (BLI_strcasecmp(channel_a->track->name, channel_b->track->name) > 0)
return 1;
@@ -2196,10 +2211,10 @@ static int channels_alpha_sort(void *a, void *b)
return 0;
}
-static int channels_total_track_sort(void *a, void *b)
+static int channels_total_track_sort(const void *a, const void *b)
{
- MovieTrackingDopesheetChannel *channel_a = a;
- MovieTrackingDopesheetChannel *channel_b = b;
+ const MovieTrackingDopesheetChannel *channel_a = a;
+ const MovieTrackingDopesheetChannel *channel_b = b;
if (channel_a->total_frames > channel_b->total_frames)
return 1;
@@ -2207,10 +2222,10 @@ static int channels_total_track_sort(void *a, void *b)
return 0;
}
-static int channels_longest_segment_sort(void *a, void *b)
+static int channels_longest_segment_sort(const void *a, const void *b)
{
- MovieTrackingDopesheetChannel *channel_a = a;
- MovieTrackingDopesheetChannel *channel_b = b;
+ const MovieTrackingDopesheetChannel *channel_a = a;
+ const MovieTrackingDopesheetChannel *channel_b = b;
if (channel_a->max_segment > channel_b->max_segment)
return 1;
@@ -2218,10 +2233,10 @@ static int channels_longest_segment_sort(void *a, void *b)
return 0;
}
-static int channels_average_error_sort(void *a, void *b)
+static int channels_average_error_sort(const void *a, const void *b)
{
- MovieTrackingDopesheetChannel *channel_a = a;
- MovieTrackingDopesheetChannel *channel_b = b;
+ const MovieTrackingDopesheetChannel *channel_a = a;
+ const MovieTrackingDopesheetChannel *channel_b = b;
if (channel_a->track->error > channel_b->track->error)
return 1;
@@ -2229,7 +2244,7 @@ static int channels_average_error_sort(void *a, void *b)
return 0;
}
-static int channels_alpha_inverse_sort(void *a, void *b)
+static int channels_alpha_inverse_sort(const void *a, const void *b)
{
if (channels_alpha_sort(a, b))
return 0;
@@ -2237,7 +2252,7 @@ static int channels_alpha_inverse_sort(void *a, void *b)
return 1;
}
-static int channels_total_track_inverse_sort(void *a, void *b)
+static int channels_total_track_inverse_sort(const void *a, const void *b)
{
if (channels_total_track_sort(a, b))
return 0;
@@ -2245,7 +2260,7 @@ static int channels_total_track_inverse_sort(void *a, void *b)
return 1;
}
-static int channels_longest_segment_inverse_sort(void *a, void *b)
+static int channels_longest_segment_inverse_sort(const void *a, const void *b)
{
if (channels_longest_segment_sort(a, b))
return 0;
@@ -2253,10 +2268,10 @@ static int channels_longest_segment_inverse_sort(void *a, void *b)
return 1;
}
-static int channels_average_error_inverse_sort(void *a, void *b)
+static int channels_average_error_inverse_sort(const void *a, const void *b)
{
- MovieTrackingDopesheetChannel *channel_a = a;
- MovieTrackingDopesheetChannel *channel_b = b;
+ const MovieTrackingDopesheetChannel *channel_a = a;
+ const MovieTrackingDopesheetChannel *channel_b = b;
if (channel_a->track->error < channel_b->track->error)
return 1;
diff --git a/source/blender/blenkernel/intern/treehash.c b/source/blender/blenkernel/intern/treehash.c
index a65bd28da97..866502c4ae1 100644
--- a/source/blender/blenkernel/intern/treehash.c
+++ b/source/blender/blenkernel/intern/treehash.c
@@ -91,7 +91,7 @@ static unsigned int tse_hash(const void *ptr)
return hash.u_int;
}
-static int tse_cmp(const void *a, const void *b)
+static bool tse_cmp(const void *a, const void *b)
{
const TreeStoreElem *tse_a = a;
const TreeStoreElem *tse_b = b;
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h
index 3a9d013f796..db33c5cec8b 100644
--- a/source/blender/blenlib/BLI_array.h
+++ b/source/blender/blenlib/BLI_array.h
@@ -84,26 +84,30 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
*
* Allow for a large 'num' value when the new size is more than double
* to allocate the exact sized array. */
-#define BLI_array_grow_items(arr, num) (( \
+#define BLI_array_reserve(arr, num) (void)( \
(((void *)(arr) == NULL) && \
((void *)(_##arr##_static) != NULL) && \
/* don't add _##arr##_count below because it must be zero */ \
- (_bli_array_totalsize_static(arr) >= _##arr##_count + num)) ? \
+ (_bli_array_totalsize_static(arr) >= _##arr##_count + (num))) ? \
/* we have an empty array and a static var big enough */ \
(void)(arr = (void *)_##arr##_static) \
: \
/* use existing static array or allocate */ \
- (LIKELY(_bli_array_totalsize(arr) >= _##arr##_count + num) ? \
+ (LIKELY(_bli_array_totalsize(arr) >= _##arr##_count + (num)) ? \
(void)0 /* do nothing */ : \
_bli_array_grow_func((void **)&(arr), _##arr##_static, \
sizeof(*(arr)), _##arr##_count, num, \
"BLI_array." #arr)) \
- ), \
- /* increment the array count, all conditions above are accounted for. */ \
- (_##arr##_count += num))
+ )
+
/* returns length of array */
-#define BLI_array_grow_one(arr) BLI_array_grow_items(arr, 1)
+
+#define BLI_array_grow_items(arr, num) \
+ (BLI_array_reserve(arr, num), (_##arr##_count += num))
+
+#define BLI_array_grow_one(arr) \
+ BLI_array_grow_items(arr, 1)
/* appends an item to the array. */
@@ -120,9 +124,9 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
(&arr[_##arr##_count - 1]) \
)
-#define BLI_array_reserve(arr, num) \
- BLI_array_grow_items(arr, num), (void)(_##arr##_count -= (num))
-
+/* appends (grows) & returns a pointer to the uninitialized memory */
+#define BLI_array_append_ret(arr) \
+ (BLI_array_reserve(arr, 1), &arr[(_##arr##_count++)])
#define BLI_array_free(arr) \
if (arr && (char *)arr != _##arr##_static) { \
diff --git a/source/blender/blenlib/BLI_compiler_typecheck.h b/source/blender/blenlib/BLI_compiler_typecheck.h
new file mode 100644
index 00000000000..551569b066d
--- /dev/null
+++ b/source/blender/blenlib/BLI_compiler_typecheck.h
@@ -0,0 +1,379 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_COMPILER_TYPECHECK_H__
+#define __BLI_COMPILER_TYPECHECK_H__
+
+/** \file BLI_compiler_typecheck.h
+ * \ingroup bli
+ *
+ * Type checking macros (often used to ensure valid use of macro args).
+ * These depend on compiler extensions and c11 in some cases.
+ */
+
+/* Causes warning:
+ * incompatible types when assigning to type 'Foo' from type 'Bar'
+ * ... the compiler optimizes away the temp var */
+#ifdef __GNUC__
+#define CHECK_TYPE(var, type) { \
+ typeof(var) *__tmp; \
+ __tmp = (type *)NULL; \
+ (void)__tmp; \
+} (void)0
+
+#define CHECK_TYPE_PAIR(var_a, var_b) { \
+ typeof(var_a) *__tmp; \
+ __tmp = (typeof(var_b) *)NULL; \
+ (void)__tmp; \
+} (void)0
+
+#define CHECK_TYPE_PAIR_INLINE(var_a, var_b) ((void)({ \
+ typeof(var_a) *__tmp; \
+ __tmp = (typeof(var_b) *)NULL; \
+ (void)__tmp; \
+}))
+
+#else
+# define CHECK_TYPE(var, type)
+# define CHECK_TYPE_PAIR(var_a, var_b)
+# define CHECK_TYPE_PAIR_INLINE(var_a, var_b) (void)0
+#endif
+
+/* can be used in simple macros */
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+# define CHECK_TYPE_INLINE(val, type) \
+ (void)((void)(((type)0) != (0 ? (val) : ((type)0))), \
+ _Generic((val), type: 0, const type: 0))
+#else
+# define CHECK_TYPE_INLINE(val, type) \
+ ((void)(((type)0) != (0 ? (val) : ((type)0))))
+#endif
+
+#define CHECK_TYPE_NONCONST(var) { \
+ void *non_const = 0 ? (var) : NULL; \
+ (void)non_const; \
+} (void)0
+
+/**
+ * CHECK_TYPE_ANY: handy macro, eg:
+ * ``CHECK_TYPE_ANY(var, Foo *, Bar *, Baz *)``
+ *
+ * excuse ridiculously long generated args.
+ * <pre>
+ * for i in range(63):
+ * args = [(chr(ord('a') + (c % 26)) + (chr(ord('0') + (c // 26)))) for c in range(i + 1)]
+ * print("#define _VA_CHECK_TYPE_ANY%d(v, %s) \\" % (i + 2, ", ".join(args)))
+ * print(" ((void)_Generic((v), %s))" % (": 0, ".join(args) + ": 0"))
+ * </pre>
+ */
+#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
+
+#define _VA_CHECK_TYPE_ANY2(v, a0) \
+ ((void)_Generic((v), a0: 0))
+#define _VA_CHECK_TYPE_ANY3(v, a0, b0) \
+ ((void)_Generic((v), a0: 0, b0: 0))
+#define _VA_CHECK_TYPE_ANY4(v, a0, b0, c0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0))
+#define _VA_CHECK_TYPE_ANY5(v, a0, b0, c0, d0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0))
+#define _VA_CHECK_TYPE_ANY6(v, a0, b0, c0, d0, e0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0))
+#define _VA_CHECK_TYPE_ANY7(v, a0, b0, c0, d0, e0, f0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0))
+#define _VA_CHECK_TYPE_ANY8(v, a0, b0, c0, d0, e0, f0, g0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0))
+#define _VA_CHECK_TYPE_ANY9(v, a0, b0, c0, d0, e0, f0, g0, h0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0))
+#define _VA_CHECK_TYPE_ANY10(v, a0, b0, c0, d0, e0, f0, g0, h0, i0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0))
+#define _VA_CHECK_TYPE_ANY11(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0))
+#define _VA_CHECK_TYPE_ANY12(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0))
+#define _VA_CHECK_TYPE_ANY13(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0))
+#define _VA_CHECK_TYPE_ANY14(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0))
+#define _VA_CHECK_TYPE_ANY15(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0))
+#define _VA_CHECK_TYPE_ANY16(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0))
+#define _VA_CHECK_TYPE_ANY17(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0))
+#define _VA_CHECK_TYPE_ANY18(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0))
+#define _VA_CHECK_TYPE_ANY19(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0))
+#define _VA_CHECK_TYPE_ANY20(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0))
+#define _VA_CHECK_TYPE_ANY21(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0))
+#define _VA_CHECK_TYPE_ANY22(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0))
+#define _VA_CHECK_TYPE_ANY23(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0))
+#define _VA_CHECK_TYPE_ANY24(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0))
+#define _VA_CHECK_TYPE_ANY25(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0))
+#define _VA_CHECK_TYPE_ANY26(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0))
+#define _VA_CHECK_TYPE_ANY27(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0))
+#define _VA_CHECK_TYPE_ANY28(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0))
+#define _VA_CHECK_TYPE_ANY29(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0))
+#define _VA_CHECK_TYPE_ANY30(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0))
+#define _VA_CHECK_TYPE_ANY31(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0))
+#define _VA_CHECK_TYPE_ANY32(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0))
+#define _VA_CHECK_TYPE_ANY33(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0))
+#define _VA_CHECK_TYPE_ANY34(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0))
+#define _VA_CHECK_TYPE_ANY35(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0))
+#define _VA_CHECK_TYPE_ANY36(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0))
+#define _VA_CHECK_TYPE_ANY37(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0))
+#define _VA_CHECK_TYPE_ANY38(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0))
+#define _VA_CHECK_TYPE_ANY39(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0))
+#define _VA_CHECK_TYPE_ANY40(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0))
+#define _VA_CHECK_TYPE_ANY41(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0))
+#define _VA_CHECK_TYPE_ANY42(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0))
+#define _VA_CHECK_TYPE_ANY43(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0))
+#define _VA_CHECK_TYPE_ANY44(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0))
+#define _VA_CHECK_TYPE_ANY45(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0))
+#define _VA_CHECK_TYPE_ANY46(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0))
+#define _VA_CHECK_TYPE_ANY47(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0))
+#define _VA_CHECK_TYPE_ANY48(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0))
+#define _VA_CHECK_TYPE_ANY49(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0))
+#define _VA_CHECK_TYPE_ANY50(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0))
+#define _VA_CHECK_TYPE_ANY51(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0))
+#define _VA_CHECK_TYPE_ANY52(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0))
+#define _VA_CHECK_TYPE_ANY53(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0))
+#define _VA_CHECK_TYPE_ANY54(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0))
+#define _VA_CHECK_TYPE_ANY55(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2, b2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0, b2: 0))
+#define _VA_CHECK_TYPE_ANY56(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2, b2, c2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0, b2: 0, c2: 0))
+#define _VA_CHECK_TYPE_ANY57(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2, b2, c2, d2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0, b2: 0, c2: 0, d2: 0))
+#define _VA_CHECK_TYPE_ANY58(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2, b2, c2, d2, e2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0, b2: 0, c2: 0, d2: 0, e2: 0))
+#define _VA_CHECK_TYPE_ANY59(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2, b2, c2, d2, e2, f2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0, b2: 0, c2: 0, d2: 0, e2: 0, f2: 0))
+#define _VA_CHECK_TYPE_ANY60(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2, b2, c2, d2, e2, f2, g2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0, b2: 0, c2: 0, d2: 0, e2: 0, f2: 0, g2: 0))
+#define _VA_CHECK_TYPE_ANY61(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2, b2, c2, d2, e2, f2, g2, h2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0, b2: 0, c2: 0, d2: 0, e2: 0, f2: 0, g2: 0, h2: 0))
+#define _VA_CHECK_TYPE_ANY62(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2, b2, c2, d2, e2, f2, g2, h2, i2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0, b2: 0, c2: 0, d2: 0, e2: 0, f2: 0, g2: 0, h2: 0, i2: 0))
+#define _VA_CHECK_TYPE_ANY63(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0, b2: 0, c2: 0, d2: 0, e2: 0, f2: 0, g2: 0, h2: 0, i2: 0, \
+ j2: 0))
+#define _VA_CHECK_TYPE_ANY64(v, a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0, q0, r0, s0, t0, u0, \
+ v0, w0, x0, y0, z0, a1, b1, c1, d1, e1, f1, g1, h1, i1, j1, k1, l1, m1, n1, o1, p1, q1, r1, s1, t1, u1, v1, w1, \
+ x1, y1, z1, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2) \
+ ((void)_Generic((v), a0: 0, b0: 0, c0: 0, d0: 0, e0: 0, f0: 0, g0: 0, h0: 0, i0: 0, j0: 0, k0: 0, l0: 0, m0: 0, \
+ n0: 0, o0: 0, p0: 0, q0: 0, r0: 0, s0: 0, t0: 0, u0: 0, v0: 0, w0: 0, x0: 0, y0: 0, z0: 0, a1: 0, b1: 0, c1: 0, \
+ d1: 0, e1: 0, f1: 0, g1: 0, h1: 0, i1: 0, j1: 0, k1: 0, l1: 0, m1: 0, n1: 0, o1: 0, p1: 0, q1: 0, r1: 0, s1: 0, \
+ t1: 0, u1: 0, v1: 0, w1: 0, x1: 0, y1: 0, z1: 0, a2: 0, b2: 0, c2: 0, d2: 0, e2: 0, f2: 0, g2: 0, h2: 0, i2: 0, \
+ j2: 0, k2: 0))
+# define CHECK_TYPE_ANY(...) VA_NARGS_CALL_OVERLOAD(_VA_CHECK_TYPE_ANY, __VA_ARGS__)
+#else
+# define CHECK_TYPE_ANY(...) (void)0
+#endif
+
+#endif /* __BLI_COMPILER_TYPECHECK_H__ */
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index dd3f62cd6d3..af2605894e3 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -41,7 +41,7 @@ extern "C" {
#endif
typedef unsigned int (*GHashHashFP) (const void *key);
-typedef int (*GHashCmpFP) (const void *a, const void *b);
+typedef bool (*GHashCmpFP) (const void *a, const void *b);
typedef void (*GHashKeyFreeFP) (void *key);
typedef void (*GHashValFreeFP) (void *val);
@@ -120,14 +120,14 @@ BLI_INLINE bool BLI_ghashIterator_done(GHashIterator *ghi) { return !ghi
* \{ */
unsigned int BLI_ghashutil_ptrhash(const void *key);
-int BLI_ghashutil_ptrcmp(const void *a, const void *b);
+bool BLI_ghashutil_ptrcmp(const void *a, const void *b);
unsigned int BLI_ghashutil_strhash_n(const char *key, size_t n);
#define BLI_ghashutil_strhash(key) ( \
CHECK_TYPE_INLINE(key, char *), \
BLI_ghashutil_strhash_p(key))
unsigned int BLI_ghashutil_strhash_p(const void *key);
-int BLI_ghashutil_strcmp(const void *a, const void *b);
+bool BLI_ghashutil_strcmp(const void *a, const void *b);
#define BLI_ghashutil_inthash(key) ( \
CHECK_TYPE_INLINE(&(key), int *), \
@@ -139,11 +139,11 @@ unsigned int BLI_ghashutil_uinthash(unsigned int key);
unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4]);
#define BLI_ghashutil_inthash_v4_p \
((GSetHashFP)BLI_ghashutil_uinthash_v4)
-int BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b);
+bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b);
#define BLI_ghashutil_inthash_v4_cmp \
BLI_ghashutil_uinthash_v4_cmp
unsigned int BLI_ghashutil_inthash_p(const void *ptr);
-int BLI_ghashutil_intcmp(const void *a, const void *b);
+bool BLI_ghashutil_intcmp(const void *a, const void *b);
/** \} */
@@ -167,7 +167,7 @@ typedef struct GHashPair {
GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second);
unsigned int BLI_ghashutil_pairhash(const void *ptr);
-int BLI_ghashutil_paircmp(const void *a, const void *b);
+bool BLI_ghashutil_paircmp(const void *a, const void *b);
void BLI_ghashutil_pairfree(void *ptr);
diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h
index 99a5fad397a..49d072ddfdc 100644
--- a/source/blender/blenlib/BLI_kdopbvh.h
+++ b/source/blender/blenlib/BLI_kdopbvh.h
@@ -89,7 +89,7 @@ void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoin
void BLI_bvhtree_balance(BVHTree *tree);
/* update: first update points/nodes, then call update_tree to refit the bounding volumes */
-int BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints);
+bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints);
void BLI_bvhtree_update_tree(BVHTree *tree);
/* collision/overlap: check two trees if they overlap, alloc's *overlap with length of the int return value */
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 697ba863603..fb388977ddf 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -67,8 +67,8 @@ void *BLI_poptail(ListBase *listbase) ATTR_NONNULL(1);
void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1);
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1);
void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1);
-void BLI_sortlist(struct ListBase *listbase, int (*cmp)(void *, void *)) ATTR_NONNULL(1, 2);
-void BLI_sortlist_r(ListBase *listbase, void *thunk, int (*cmp)(void *, void *, void *)) ATTR_NONNULL(1, 3);
+void BLI_sortlist(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2);
+void BLI_sortlist_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) ATTR_NONNULL(1, 3);
void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1);
int BLI_countlist(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1);
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h
index 5f94f04e0a8..494bc4083ba 100644
--- a/source/blender/blenlib/BLI_math_base.h
+++ b/source/blender/blenlib/BLI_math_base.h
@@ -83,8 +83,8 @@ static const int NAN_INT = 0x7FC00000;
# define NAN_FLT (*((float *)(&NAN_INT)))
#endif
-/* do not redefine functions from C99 or POSIX.1-2001 */
-#if !(defined(_ISOC99_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L))
+/* do not redefine functions from C99, POSIX.1-2001 or MSVC12 (partial C99) */
+#if !(defined(_ISOC99_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || (defined(_MSC_VER) && _MSC_VER >= 1800))
#ifndef sqrtf
#define sqrtf(a) ((float)sqrt(a))
@@ -138,7 +138,7 @@ static const int NAN_INT = 0x7FC00000;
#define copysignf(a, b) ((float)copysign(a, b))
#endif
-#endif /* C99 or POSIX.1-2001 */
+#endif /* C99, POSIX.1-2001 or MSVC12 (partial C99) */
#ifdef WIN32
# if defined(_MSC_VER)
diff --git a/source/blender/blenlib/BLI_math_color_blend.h b/source/blender/blenlib/BLI_math_color_blend.h
index 2535a31ccc4..d966676e19e 100644
--- a/source/blender/blenlib/BLI_math_color_blend.h
+++ b/source/blender/blenlib/BLI_math_color_blend.h
@@ -78,22 +78,22 @@ MINLINE void blend_color_darken_float(float dst[4], const float src1[4], const f
MINLINE void blend_color_erase_alpha_float(float dst[4], const float src1[4], const float src2[4]);
MINLINE void blend_color_add_alpha_float(float dst[4], const float src1[4], const float src2[4]);
-MINLINE void blend_color_overlay_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_burn_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_linearburn_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_dodge_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_screen_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_softlight_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_pinlight_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_linearlight_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_vividlight_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_difference_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_exclusion_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_color_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_hue_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_saturation_float(float dst[4], const float src1[4], const float src2[2]);
-MINLINE void blend_color_luminosity_float(float dst[4], const float src1[4], const float src2[2]);
+MINLINE void blend_color_overlay_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_burn_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_linearburn_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_dodge_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_screen_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_softlight_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_pinlight_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_linearlight_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_vividlight_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_difference_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_exclusion_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_color_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_hue_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_saturation_float(float dst[4], const float src1[4], const float src2[4]);
+MINLINE void blend_color_luminosity_float(float dst[4], const float src1[4], const float src2[4]);
MINLINE void blend_color_interpolate_float(float dst[4], const float src1[4], const float src2[4], float t);
diff --git a/source/blender/blenlib/BLI_stack.h b/source/blender/blenlib/BLI_stack.h
index 1e0b29bc7e8..a8c4478c450 100644
--- a/source/blender/blenlib/BLI_stack.h
+++ b/source/blender/blenlib/BLI_stack.h
@@ -46,6 +46,9 @@ void BLI_stack_push(BLI_Stack *stack, const void *src) ATTR_NONNULL();
void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n) ATTR_NONNULL();
void BLI_stack_pop(BLI_Stack *stack, void *dst) ATTR_NONNULL();
+void *BLI_stack_peek(BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void BLI_stack_discard(BLI_Stack *stack) ATTR_NONNULL();
+
size_t BLI_stack_count(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
bool BLI_stack_is_empty(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
diff --git a/source/blender/blenlib/BLI_stackdefines.h b/source/blender/blenlib/BLI_stackdefines.h
index da9bf5ea04c..864a7704aa9 100644
--- a/source/blender/blenlib/BLI_stackdefines.h
+++ b/source/blender/blenlib/BLI_stackdefines.h
@@ -64,6 +64,13 @@
stack[_i] = stack[_##stack##_index]; \
} \
} (void)0
+#define STACK_DISCARD(stack, n) \
+ { \
+ const unsigned int _n = n; \
+ BLI_assert(_##stack##_index >= _n); \
+ (void)stack; \
+ _##stack##_index -= _n; \
+ } (void)0
#ifdef __GNUC__
#define STACK_SWAP(stack_a, stack_b) { \
SWAP(typeof(stack_a), stack_a, stack_b); \
diff --git a/source/blender/blenlib/BLI_strict_flags.h b/source/blender/blenlib/BLI_strict_flags.h
index 1d595ff3bf3..964ee06469d 100644
--- a/source/blender/blenlib/BLI_strict_flags.h
+++ b/source/blender/blenlib/BLI_strict_flags.h
@@ -28,13 +28,15 @@
*/
#ifdef __GNUC__
-# pragma GCC diagnostic error "-Wsign-conversion"
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
# pragma GCC diagnostic error "-Wsign-compare"
# pragma GCC diagnostic error "-Wconversion"
# endif
-# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408 /* gcc4.8+ only (behavior changed to ignore globals)*/
+# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408
+ /* gcc4.8+ only (behavior changed to ignore globals)*/
# pragma GCC diagnostic error "-Wshadow"
+ /* older gcc changed behavior with ternary */
+# pragma GCC diagnostic error "-Wsign-conversion"
# endif
/* pedantic gives too many issues, developers can define this for own use */
# ifdef WARN_PEDANTIC
diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h
index 683b3c4c438..a829cc60106 100644
--- a/source/blender/blenlib/BLI_utildefines.h
+++ b/source/blender/blenlib/BLI_utildefines.h
@@ -47,11 +47,15 @@
#define _VA_NARGS_RETURN_COUNT(\
_1_, _2_, _3_, _4_, _5_, _6_, _7_, _8_, _9_, _10_, _11_, _12_, _13_, _14_, _15_, _16_, \
_17_, _18_, _19_, _20_, _21_, _22_, _23_, _24_, _25_, _26_, _27_, _28_, _29_, _30_, _31_, _32_, \
+ _33_, _34_, _35_, _36_, _37_, _38_, _39_, _40_, _41_, _42_, _43_, _44_, _45_, _46_, _47_, _48_, \
+ _49_, _50_, _51_, _52_, _53_, _54_, _55_, _56_, _57_, _58_, _59_, _60_, _61_, _62_, _63_, _64_, \
count, ...) count
#define _VA_NARGS_EXPAND(args) _VA_NARGS_RETURN_COUNT args
#define _VA_NARGS_COUNT_MAX32(...) _VA_NARGS_EXPAND((__VA_ARGS__, \
- 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, \
- 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
+ 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \
+ 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, \
+ 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \
+ 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0))
#define _VA_NARGS_OVERLOAD_MACRO2(name, count) name##count
#define _VA_NARGS_OVERLOAD_MACRO1(name, count) _VA_NARGS_OVERLOAD_MACRO2(name, count)
#define _VA_NARGS_OVERLOAD_MACRO(name, count) _VA_NARGS_OVERLOAD_MACRO1(name, count)
@@ -67,6 +71,9 @@
# define MAX2(x, y) (_TYPECHECK(x, y), (((x) > (y) ? (x) : (y))))
#endif
+/* include after _VA_NARGS macro */
+#include "BLI_compiler_typecheck.h"
+
/* min/max */
#if defined(__GNUC__) || defined(__clang__)
@@ -151,48 +158,6 @@
/* some math and copy defines */
-/* Causes warning:
- * incompatible types when assigning to type 'Foo' from type 'Bar'
- * ... the compiler optimizes away the temp var */
-#ifdef __GNUC__
-#define CHECK_TYPE(var, type) { \
- typeof(var) *__tmp; \
- __tmp = (type *)NULL; \
- (void)__tmp; \
-} (void)0
-
-#define CHECK_TYPE_PAIR(var_a, var_b) { \
- typeof(var_a) *__tmp; \
- __tmp = (typeof(var_b) *)NULL; \
- (void)__tmp; \
-} (void)0
-
-#define CHECK_TYPE_PAIR_INLINE(var_a, var_b) ((void)({ \
- typeof(var_a) *__tmp; \
- __tmp = (typeof(var_b) *)NULL; \
- (void)__tmp; \
-}))
-
-#else
-# define CHECK_TYPE(var, type)
-# define CHECK_TYPE_PAIR(var_a, var_b)
-# define CHECK_TYPE_PAIR_INLINE(var_a, var_b) (void)0
-#endif
-
-/* can be used in simple macros */
-#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
-# define CHECK_TYPE_INLINE(val, type) \
- (void)((void)(((type)0) != (0 ? (val) : ((type)0))), \
- _Generic((val), type: 0, const type: 0))
-#else
-# define CHECK_TYPE_INLINE(val, type) \
- ((void)(((type)0) != (0 ? (val) : ((type)0))))
-#endif
-
-#define CHECK_TYPE_NONCONST(var) { \
- void *non_const = 0 ? (var) : NULL; \
- (void)non_const; \
-} (void)0
#define SWAP(type, a, b) { \
type sw_ap; \
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index dd02bcf22a9..9efa20da13e 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -118,6 +118,7 @@ set(SRC
BLI_callbacks.h
BLI_compiler_attrs.h
BLI_compiler_compat.h
+ BLI_compiler_typecheck.h
BLI_convexhull2d.h
BLI_dial.h
BLI_dlrbTree.h
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
index 8bd35f651b7..49a3c466727 100644
--- a/source/blender/blenlib/intern/BLI_args.c
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -91,15 +91,17 @@ static unsigned int keyhash(const void *ptr)
return case_strhash(k->arg); /* ^ BLI_ghashutil_inthash((void *)k->pass); */
}
-static int keycmp(const void *a, const void *b)
+static bool keycmp(const void *a, const void *b)
{
const bAKey *ka = a;
const bAKey *kb = b;
if (ka->pass == kb->pass || ka->pass == -1 || kb->pass == -1) { /* -1 is wildcard for pass */
- if (ka->case_str == 1 || kb->case_str == 1)
- return BLI_strcasecmp(ka->arg, kb->arg);
- else
- return strcmp(ka->arg, kb->arg);
+ if (ka->case_str == 1 || kb->case_str == 1) {
+ return (BLI_strcasecmp(ka->arg, kb->arg) != 0);
+ }
+ else {
+ return (strcmp(ka->arg, kb->arg) != 0);
+ }
}
else {
return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass);
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 74d7fdc88cb..6747e5c4e7e 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -155,7 +155,7 @@ BLI_INLINE Entry *ghash_lookup_entry_ex(GHash *gh, const void *key,
Entry *e;
for (e = gh->buckets[hash]; e; e = e->next) {
- if (UNLIKELY(gh->cmpfp(key, e->key) == 0)) {
+ if (UNLIKELY(gh->cmpfp(key, e->key) == false)) {
return e;
}
}
@@ -251,7 +251,7 @@ static Entry *ghash_remove_ex(GHash *gh, void *key, GHashKeyFreeFP keyfreefp, GH
Entry *e_prev = NULL;
for (e = gh->buckets[hash]; e; e = e->next) {
- if (UNLIKELY(gh->cmpfp(key, e->key) == 0)) {
+ if (UNLIKELY(gh->cmpfp(key, e->key) == false)) {
Entry *e_next = e->next;
if (keyfreefp) keyfreefp(e->key);
@@ -683,12 +683,9 @@ unsigned int BLI_ghashutil_ptrhash(const void *key)
return (unsigned int)y;
}
#endif
-int BLI_ghashutil_ptrcmp(const void *a, const void *b)
+bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
{
- if (a == b)
- return 0;
- else
- return (a < b) ? -1 : 1;
+ return (a != b);
}
unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4])
@@ -704,9 +701,9 @@ unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4])
return hash;
}
-int BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b)
+bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b)
{
- return memcmp(a, b, sizeof(unsigned int[4]));
+ return (memcmp(a, b, sizeof(unsigned int[4])) != 0);
}
unsigned int BLI_ghashutil_uinthash(unsigned int key)
@@ -735,12 +732,9 @@ unsigned int BLI_ghashutil_inthash_p(const void *ptr)
return (unsigned int)(key & 0xffffffff);
}
-int BLI_ghashutil_intcmp(const void *a, const void *b)
+bool BLI_ghashutil_intcmp(const void *a, const void *b)
{
- if (a == b)
- return 0;
- else
- return (a < b) ? -1 : 1;
+ return (a != b);
}
/**
@@ -774,9 +768,9 @@ unsigned int BLI_ghashutil_strhash_p(const void *ptr)
return h;
}
-int BLI_ghashutil_strcmp(const void *a, const void *b)
+bool BLI_ghashutil_strcmp(const void *a, const void *b)
{
- return strcmp(a, b);
+ return (strcmp(a, b) != 0);
}
GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second)
@@ -794,15 +788,13 @@ unsigned int BLI_ghashutil_pairhash(const void *ptr)
return hash ^ BLI_ghashutil_ptrhash(pair->second);
}
-int BLI_ghashutil_paircmp(const void *a, const void *b)
+bool BLI_ghashutil_paircmp(const void *a, const void *b)
{
const GHashPair *A = a;
const GHashPair *B = b;
- int cmp = BLI_ghashutil_ptrcmp(A->first, B->first);
- if (cmp == 0)
- return BLI_ghashutil_ptrcmp(A->second, B->second);
- return cmp;
+ return (BLI_ghashutil_ptrcmp(A->first, B->first) ||
+ BLI_ghashutil_ptrcmp(A->second, B->second));
}
void BLI_ghashutil_pairfree(void *ptr)
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index dbacb0f3451..d28215ee8ed 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -979,7 +979,7 @@ void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoin
/* call before BLI_bvhtree_update_tree() */
-int BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints)
+bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints)
{
BVHNode *node = NULL;
axis_t axis_iter;
diff --git a/source/blender/blenlib/intern/buffer.c b/source/blender/blenlib/intern/buffer.c
index 4e570823319..9e96205a5e8 100644
--- a/source/blender/blenlib/intern/buffer.c
+++ b/source/blender/blenlib/intern/buffer.c
@@ -38,17 +38,14 @@ static void *buffer_alloc(BLI_Buffer *buffer, int len)
static void *buffer_realloc(BLI_Buffer *buffer, int len)
{
- if (buffer->flag & BLI_BUFFER_USE_CALLOC) {
- return MEM_recallocN(buffer->data, buffer->elem_size * len);
- }
- else {
- return MEM_reallocN(buffer->data, buffer->elem_size * len);
- }
+ return ((buffer->flag & BLI_BUFFER_USE_CALLOC) ?
+ MEM_recallocN_id : MEM_reallocN_id)
+ (buffer->data, buffer->elem_size * len, "BLI_Buffer.data");
}
void BLI_buffer_resize(BLI_Buffer *buffer, int new_count)
{
- if (new_count > buffer->alloc_count) {
+ if (UNLIKELY(new_count > buffer->alloc_count)) {
if (buffer->flag & BLI_BUFFER_USE_STATIC) {
void *orig = buffer->data;
@@ -65,12 +62,7 @@ void BLI_buffer_resize(BLI_Buffer *buffer, int new_count)
buffer->alloc_count = new_count;
}
- if (buffer->data) {
- buffer->data = buffer_realloc(buffer, buffer->alloc_count);
- }
- else {
- buffer->data = buffer_alloc(buffer, buffer->alloc_count);
- }
+ buffer->data = buffer_realloc(buffer, buffer->alloc_count);
}
}
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index abf15d57cf7..d9cf8971246 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -173,7 +173,7 @@ void BLI_freelinkN(ListBase *listbase, void *vlink)
* (which should return 1 iff its first arg should come after its second arg).
* This uses insertion sort, so NOT ok for large list.
*/
-void BLI_sortlist(ListBase *listbase, int (*cmp)(void *, void *))
+void BLI_sortlist(ListBase *listbase, int (*cmp)(const void *, const void *))
{
Link *current = NULL;
Link *previous = NULL;
@@ -195,7 +195,7 @@ void BLI_sortlist(ListBase *listbase, int (*cmp)(void *, void *))
}
}
-void BLI_sortlist_r(ListBase *listbase, void *thunk, int (*cmp)(void *, void *, void *))
+void BLI_sortlist_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *))
{
Link *current = NULL;
Link *previous = NULL;
diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c
index 2522fe5f6c9..73a7259ddcd 100644
--- a/source/blender/blenlib/intern/math_color_blend_inline.c
+++ b/source/blender/blenlib/intern/math_color_blend_inline.c
@@ -781,7 +781,7 @@ MINLINE void blend_color_add_alpha_float(float dst[4], const float src1[4], cons
}
}
-MINLINE void blend_color_overlay_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_overlay_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -807,7 +807,7 @@ MINLINE void blend_color_overlay_float(float dst[3], const float src1[3], const
}
-MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], const float src2[2])
+MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -832,7 +832,7 @@ MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], cons
}
}
-MINLINE void blend_color_burn_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_burn_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -850,7 +850,7 @@ MINLINE void blend_color_burn_float(float dst[3], const float src1[3], const flo
}
}
-MINLINE void blend_color_linearburn_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_linearburn_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -869,7 +869,7 @@ MINLINE void blend_color_linearburn_float(float dst[3], const float src1[3], con
}
-MINLINE void blend_color_dodge_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_dodge_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -887,7 +887,7 @@ MINLINE void blend_color_dodge_float(float dst[3], const float src1[3], const fl
}
}
-MINLINE void blend_color_screen_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_screen_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -905,7 +905,7 @@ MINLINE void blend_color_screen_float(float dst[3], const float src1[3], const f
}
}
-MINLINE void blend_color_softlight_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_softlight_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -930,7 +930,7 @@ MINLINE void blend_color_softlight_float(float dst[3], const float src1[3], cons
}
}
-MINLINE void blend_color_pinlight_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_pinlight_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -956,7 +956,7 @@ MINLINE void blend_color_pinlight_float(float dst[3], const float src1[3], const
}
-MINLINE void blend_color_linearlight_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_linearlight_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -982,7 +982,7 @@ MINLINE void blend_color_linearlight_float(float dst[3], const float src1[3], co
}
-MINLINE void blend_color_vividlight_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_vividlight_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -1013,7 +1013,7 @@ MINLINE void blend_color_vividlight_float(float dst[3], const float src1[3], con
}
}
-MINLINE void blend_color_difference_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_difference_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -1031,7 +1031,7 @@ MINLINE void blend_color_difference_float(float dst[3], const float src1[3], con
}
-MINLINE void blend_color_exclusion_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_exclusion_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -1050,7 +1050,7 @@ MINLINE void blend_color_exclusion_float(float dst[3], const float src1[3], cons
}
-MINLINE void blend_color_color_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_color_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -1078,7 +1078,7 @@ MINLINE void blend_color_color_float(float dst[3], const float src1[3], const fl
}
-MINLINE void blend_color_hue_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_hue_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -1104,7 +1104,7 @@ MINLINE void blend_color_hue_float(float dst[3], const float src1[3], const floa
}
}
-MINLINE void blend_color_saturation_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_saturation_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
@@ -1131,7 +1131,7 @@ MINLINE void blend_color_saturation_float(float dst[3], const float src1[3], con
}
}
-MINLINE void blend_color_luminosity_float(float dst[3], const float src1[3], const float src2[3])
+MINLINE void blend_color_luminosity_float(float dst[4], const float src1[4], const float src2[4])
{
const float fac = src2[3];
if (fac != 0.0f && fac < 1.0f) {
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 17a1dcbf34d..496e5362cc4 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -160,6 +160,12 @@ float area_poly_v3(const float verts[][3], unsigned int nr)
return normal_poly_v3(n, verts, nr) * 0.5f;
}
+/**
+ * Scalar cross product of a 2d polygon.
+ *
+ * - equivalent to ``area * 2``
+ * - useful for checking polygon winding (a positive value is clockwise).
+ */
float cross_poly_v2(const float verts[][2], unsigned int nr)
{
unsigned int a;
@@ -1786,7 +1792,10 @@ float closest_to_line_v2(float cp[2], const float p[2], const float l1[2], const
return lambda;
}
-/* little sister we only need to know lambda */
+/**
+ * A simplified version of #closest_to_line_v3
+ * we only need to return the ``lambda``
+ */
float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
{
float h[3], u[3];
@@ -3193,7 +3202,7 @@ void map_to_tube(float *r_u, float *r_v, const float x, const float y, const flo
len = sqrtf(x * x + y * y);
if (len > 0.0f) {
- *r_u = (float)((1.0 - (atan2(x / len, y / len) / M_PI)) / 2.0);
+ *r_u = (1.0f - (atan2f(x / len, y / len) / (float)M_PI)) / 2.0f;
}
else {
*r_v = *r_u = 0.0f; /* to avoid un-initialized variables */
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 141f9201689..9a6515daf68 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -366,7 +366,7 @@ void mat3_to_quat_is_ok(float q[4], float wmat[3][3])
mul_m3_v3(matn, mat[0]);
/* and align x-axes */
- angle = (float)(0.5 * atan2(mat[0][1], mat[0][0]));
+ angle = 0.5f * atan2f(mat[0][1], mat[0][0]);
co = cosf(angle);
si = sinf(angle);
@@ -765,7 +765,7 @@ void tri_to_quat_ex(float quat[4], const float v1[3], const float v2[3], const f
vec[2] = 0.0f;
normalize_v3(vec);
- angle = (float)(0.5 * atan2(vec[1], vec[0]));
+ angle = 0.5f * atan2f(vec[1], vec[0]);
co = cosf(angle);
si = sinf(angle);
q2[0] = co;
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 5529433f6c9..da9d5bd3f49 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -957,6 +957,18 @@ MINLINE bool compare_v4v4(const float v1[4], const float v2[4], const float limi
return false;
}
+/**
+ * <pre>
+ * + l1
+ * |
+ * neg <- | -> pos
+ * |
+ * + l2
+ * </pre>
+ *
+ * \return Positive value when 'pt' is left-of-line
+ * (looking from 'l1' -> 'l2').
+ */
MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2])
{
return (((l1[0] - pt[0]) * (l2[1] - pt[1])) -
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index a7fa443cfc4..d5af980e373 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -873,9 +873,12 @@ bool BLI_path_abs(char *path, const char *basepath)
char tmp[FILE_MAX];
char base[FILE_MAX];
#ifdef WIN32
- char vol[3] = {'\0', '\0', '\0'};
- BLI_strncpy(vol, path, 3);
+ /* without this: "" --> "C:\" */
+ if (*path == '\0') {
+ return wasrelative;
+ }
+
/* we are checking here if we have an absolute path that is not in the current
* blend file as a lib main - we are basically checking for the case that a
* UNIX root '/' is passed.
diff --git a/source/blender/blenlib/intern/polyfill2d.c b/source/blender/blenlib/intern/polyfill2d.c
index a00d95a075f..16cf7ff960b 100644
--- a/source/blender/blenlib/intern/polyfill2d.c
+++ b/source/blender/blenlib/intern/polyfill2d.c
@@ -567,7 +567,7 @@ static void pf_triangulate(PolyFill *pf)
#ifdef USE_CLIP_EVEN
#ifdef USE_CLIP_SWEEP
- pi_ear_init = reverse ? pi_next->next : pi_prev->prev;
+ pi_ear_init = reverse ? pi_prev->prev : pi_next->next;
#else
pi_ear_init = pi_next->next;
#endif
diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c
index 828cb3a580b..9fc1db1f1e4 100644
--- a/source/blender/blenlib/intern/scanfill_utils.c
+++ b/source/blender/blenlib/intern/scanfill_utils.c
@@ -132,12 +132,12 @@ static ListBase *edge_isect_ls_add(GHash *isect_hash, ScanFillEdge *eed, ScanFil
return e_ls;
}
-static int edge_isect_ls_sort_cb(void *thunk, void *def_a_ptr, void *def_b_ptr)
+static int edge_isect_ls_sort_cb(void *thunk, const void *def_a_ptr, const void *def_b_ptr)
{
const float *co = thunk;
- ScanFillIsect *i_a = (ScanFillIsect *)(((LinkData *)def_a_ptr)->data);
- ScanFillIsect *i_b = (ScanFillIsect *)(((LinkData *)def_b_ptr)->data);
+ const ScanFillIsect *i_a = ((LinkData *)def_a_ptr)->data;
+ const ScanFillIsect *i_b = ((LinkData *)def_b_ptr)->data;
const float a = len_squared_v2v2(co, i_a->co);
const float b = len_squared_v2v2(co, i_b->co);
diff --git a/source/blender/blenlib/intern/stack.c b/source/blender/blenlib/intern/stack.c
index 58029120de9..2d3a2f77a3e 100644
--- a/source/blender/blenlib/intern/stack.c
+++ b/source/blender/blenlib/intern/stack.c
@@ -48,8 +48,6 @@
((void)0, (((char *)(_stack)->chunk_curr->data) + \
((_stack)->elem_size * (_stack)->chunk_index)))
-#define IS_POW2(a) (((a) & ((a) - 1)) == 0)
-
struct StackChunk {
struct StackChunk *next;
char data[0];
@@ -96,11 +94,6 @@ BLI_Stack *BLI_stack_new_ex(const size_t elem_size, const char *description,
/* force init */
stack->chunk_index = stack->chunk_elem_max - 1;
- /* ensure we have a correctly rounded size */
- BLI_assert((IS_POW2(stack->elem_size) == 0) ||
- (IS_POW2((stack->chunk_elem_max * stack->elem_size) +
- (sizeof(struct StackChunk) + MEM_SIZE_OVERHEAD))));
-
return stack;
}
@@ -182,6 +175,31 @@ void BLI_stack_pop(BLI_Stack *stack, void *dst)
BLI_assert(BLI_stack_is_empty(stack) == false);
memcpy(dst, CHUNK_LAST_ELEM(stack), stack->elem_size);
+
+ BLI_stack_discard(stack);
+}
+
+void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n)
+{
+ BLI_assert(n <= BLI_stack_count(stack));
+
+ while (n--) {
+ BLI_stack_pop(stack, dst);
+ dst = (void *)((char *)dst + stack->elem_size);
+ }
+}
+
+void *BLI_stack_peek(BLI_Stack *stack)
+{
+ BLI_assert(BLI_stack_is_empty(stack) == false);
+
+ return CHUNK_LAST_ELEM(stack);
+}
+
+void BLI_stack_discard(BLI_Stack *stack)
+{
+ BLI_assert(BLI_stack_is_empty(stack) == false);
+
#ifdef USE_TOTELEM
stack->totelem--;
#endif
@@ -198,16 +216,6 @@ void BLI_stack_pop(BLI_Stack *stack, void *dst)
}
}
-void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n)
-{
- BLI_assert(n <= BLI_stack_count(stack));
-
- while (n--) {
- BLI_stack_pop(stack, dst);
- dst = (void *)((char *)dst + stack->elem_size);
- }
-}
-
size_t BLI_stack_count(const BLI_Stack *stack)
{
#ifdef USE_TOTELEM
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 8561903ce04..aea35963269 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -1862,6 +1862,7 @@ static void direct_link_palette(FileData *fd, Palette *palette)
{
/* palette itself has been read */
link_list(fd, &palette->colors);
+ BLI_listbase_clear(&palette->deleted);
}
static void lib_link_paint_curve(FileData *UNUSED(fd), Main *main)
@@ -6237,7 +6238,6 @@ static void direct_link_region(FileData *fd, ARegion *ar, int spacetype)
rv3d->depths = NULL;
rv3d->gpuoffscreen = NULL;
- rv3d->ri = NULL;
rv3d->render_engine = NULL;
rv3d->sms = NULL;
rv3d->smooth_timer = NULL;
@@ -8995,10 +8995,10 @@ static ID *append_named_part_ex(const bContext *C, Main *mainl, FileData *fd, co
ob = (Object *)id;
- /* link at active layer (view3d->lay if in context, else scene->lay */
+ /* link at active layer (view3d if available in context, else scene one */
if ((flag & FILE_ACTIVELAY)) {
View3D *v3d = CTX_wm_view3d(C);
- ob->lay = v3d ? v3d->layact : scene->lay;
+ ob->lay = BKE_screen_view3d_layer_active(v3d, scene);
}
ob->mode = OB_MODE_OBJECT;
diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c
index 06d871c8db0..40b756a3f7c 100644
--- a/source/blender/blenloader/intern/versioning_250.c
+++ b/source/blender/blenloader/intern/versioning_250.c
@@ -89,9 +89,6 @@
#include "NOD_socket.h"
-//XXX #include "BIF_butspace.h" // badlevel, for do_versions, patching event codes
-//XXX #include "BIF_filelist.h" // badlevel too, where to move this? - elubie
-//XXX #include "BIF_previewrender.h" // bedlelvel, for struct RenderInfo
#include "BLO_readfile.h"
#include "BLO_undofile.h"
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index 8e760a9c9f6..d8da0a12b50 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -350,12 +350,19 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
for (br = main->brush.first; br; br = br->id.next) {
br->fill_threshold = 0.2f;
}
- }
- if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
- Scene *scene;
- for (scene = main->scene.first; scene; scene = scene->id.next) {
- scene->r.preview_start_resolution = 64;
+ if (!DNA_struct_elem_find(fd->filesdna, "BevelModifierData", "int", "mat")) {
+ Object *ob;
+ for (ob = main->object.first; ob; ob = ob->id.next) {
+ ModifierData *md;
+
+ for (md = ob->modifiers.first; md; md = md->next) {
+ if (md->type == eModifierType_Bevel) {
+ BevelModifierData *bmd = (BevelModifierData *)md;
+ bmd->mat = -1;
+ }
+ }
+ }
}
}
@@ -374,4 +381,28 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
+
+ if (!MAIN_VERSION_ATLEAST(main, 272, 0)) {
+ if (!DNA_struct_elem_find(fd->filesdna, "RenderData", "int", "preview_start_resolution")) {
+ Scene *scene;
+ for (scene = main->scene.first; scene; scene = scene->id.next) {
+ scene->r.preview_start_resolution = 64;
+ }
+ }
+ }
+
+ if (!MAIN_VERSION_ATLEAST(main, 272, 1)) {
+ Brush *br;
+ for (br = main->brush.first; br; br = br->id.next) {
+ if ((br->ob_mode & OB_MODE_SCULPT) && ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK))
+ br->alpha = 1.0f;
+ }
+ }
+
+ if (!DNA_struct_elem_find(fd->filesdna, "Image", "float", "gen_color")) {
+ Image *image;
+ for (image = main->image.first; image != NULL; image = image->id.next) {
+ image->gen_color[3] = 1.0f;
+ }
+ }
}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index 217d1f0821f..1afcac313a2 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -99,6 +99,7 @@ void BLO_update_defaults_startup_blend(Main *bmain)
linestyle->sort_key = LS_SORT_KEY_DISTANCE_FROM_CAMERA;
linestyle->integration_type = LS_INTEGRATION_MEAN;
linestyle->texstep = 1.0;
+ linestyle->chain_count = 10;
}
{
diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt
index a43e835f022..50d3ac30ddc 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -140,6 +140,8 @@ set(SRC
tools/bmesh_intersect.h
tools/bmesh_path.c
tools/bmesh_path.h
+ tools/bmesh_region_match.c
+ tools/bmesh_region_match.h
tools/bmesh_triangulate.c
tools/bmesh_triangulate.h
tools/bmesh_wireframe.c
diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h
index 8b5250b7c1e..4efc6aa16f8 100644
--- a/source/blender/bmesh/bmesh.h
+++ b/source/blender/bmesh/bmesh.h
@@ -58,8 +58,8 @@
*
* \subsection bm_loop The Loop
*
- * Loops define the boundary loop of a face. Each loop logically corresponds to an edge,
- * which is defined by the loop and next loop's vertices.
+ * Each loop connects the face to one of its corner vertices,
+ * and also references an edge which connects this loop's vertex to the next loop's vertex.
*
* Loops store several handy pointers:
*
diff --git a/source/blender/bmesh/bmesh_tools.h b/source/blender/bmesh/bmesh_tools.h
index baffeb774b6..f7f767f91bf 100644
--- a/source/blender/bmesh/bmesh_tools.h
+++ b/source/blender/bmesh/bmesh_tools.h
@@ -41,6 +41,7 @@ extern "C" {
#include "tools/bmesh_edgenet.h"
#include "tools/bmesh_edgesplit.h"
#include "tools/bmesh_path.h"
+#include "tools/bmesh_region_match.h"
#include "tools/bmesh_triangulate.h"
#ifdef __cplusplus
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index eef1e7bbb4f..e0348fea636 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -505,7 +505,7 @@ static void bm_vert_attrs_copy(BMesh *source_mesh, BMesh *target_mesh,
return;
}
copy_v3_v3(target_vertex->no, source_vertex->no);
- CustomData_bmesh_free_block_data(&target_mesh->vdata, &target_vertex->head.data);
+ CustomData_bmesh_free_block_data(&target_mesh->vdata, target_vertex->head.data);
CustomData_bmesh_copy_data(&source_mesh->vdata, &target_mesh->vdata,
source_vertex->head.data, &target_vertex->head.data);
}
@@ -517,7 +517,7 @@ static void bm_edge_attrs_copy(BMesh *source_mesh, BMesh *target_mesh,
BLI_assert(!"BMEdge: source and targer match");
return;
}
- CustomData_bmesh_free_block_data(&target_mesh->edata, &target_edge->head.data);
+ CustomData_bmesh_free_block_data(&target_mesh->edata, target_edge->head.data);
CustomData_bmesh_copy_data(&source_mesh->edata, &target_mesh->edata,
source_edge->head.data, &target_edge->head.data);
}
@@ -529,7 +529,7 @@ static void bm_loop_attrs_copy(BMesh *source_mesh, BMesh *target_mesh,
BLI_assert(!"BMLoop: source and targer match");
return;
}
- CustomData_bmesh_free_block_data(&target_mesh->ldata, &target_loop->head.data);
+ CustomData_bmesh_free_block_data(&target_mesh->ldata, target_loop->head.data);
CustomData_bmesh_copy_data(&source_mesh->ldata, &target_mesh->ldata,
source_loop->head.data, &target_loop->head.data);
}
@@ -542,7 +542,7 @@ static void bm_face_attrs_copy(BMesh *source_mesh, BMesh *target_mesh,
return;
}
copy_v3_v3(target_face->no, source_face->no);
- CustomData_bmesh_free_block_data(&target_mesh->pdata, &target_face->head.data);
+ CustomData_bmesh_free_block_data(&target_mesh->pdata, target_face->head.data);
CustomData_bmesh_copy_data(&source_mesh->pdata, &target_mesh->pdata,
source_face->head.data, &target_face->head.data);
target_face->mat_nr = source_face->mat_nr;
diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c
index 1f942dad048..eb7b9f78ef4 100644
--- a/source/blender/bmesh/intern/bmesh_core.c
+++ b/source/blender/bmesh/intern/bmesh_core.c
@@ -1473,8 +1473,10 @@ BMVert *bmesh_semv(BMesh *bm, BMVert *tv, BMEdge *e, BMEdge **r_e)
valence2 = bmesh_disk_count(tv);
#endif
+ /* order of 'e_new' verts should match 'e'
+ * (so extruded faces don't flip) */
v_new = BM_vert_create(bm, tv->co, tv, BM_CREATE_NOP);
- e_new = BM_edge_create(bm, v_new, tv, e, BM_CREATE_NOP);
+ e_new = BM_edge_create(bm, tv, v_new, e, BM_CREATE_NOP);
bmesh_disk_edge_remove(e_new, tv);
bmesh_disk_edge_remove(e_new, v_new);
diff --git a/source/blender/bmesh/intern/bmesh_interp.c b/source/blender/bmesh/intern/bmesh_interp.c
index 306b6e74350..a32f28169f6 100644
--- a/source/blender/bmesh/intern/bmesh_interp.c
+++ b/source/blender/bmesh/intern/bmesh_interp.c
@@ -54,7 +54,7 @@ static void bm_data_interp_from_elem(CustomData *data_layer, BMElem *ele1, BMEle
/* do nothing */
}
else {
- CustomData_bmesh_free_block_data(data_layer, &ele_dst->head.data);
+ CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
CustomData_bmesh_copy_data(data_layer, data_layer, ele1->head.data, &ele_dst->head.data);
}
}
@@ -63,7 +63,7 @@ static void bm_data_interp_from_elem(CustomData *data_layer, BMElem *ele1, BMEle
/* do nothing */
}
else {
- CustomData_bmesh_free_block_data(data_layer, &ele_dst->head.data);
+ CustomData_bmesh_free_block_data(data_layer, ele_dst->head.data);
CustomData_bmesh_copy_data(data_layer, data_layer, ele2->head.data, &ele_dst->head.data);
}
}
diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c
index 91b9774634d..476878ad38c 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.c
+++ b/source/blender/bmesh/intern/bmesh_iterators.c
@@ -338,50 +338,18 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const
# define USE_IMMUTABLE_ASSERT
#endif
-void bmiter__vert_of_mesh_begin(struct BMIter__vert_of_mesh *iter)
+void bmiter__elem_of_mesh_begin(struct BMIter__elem_of_mesh *iter)
{
#ifdef USE_IMMUTABLE_ASSERT
- ((BMIter *)iter)->count = iter->bm->totvert;
+ ((BMIter *)iter)->count = BLI_mempool_count(iter->pooliter.pool);
#endif
- BLI_mempool_iternew(iter->bm->vpool, &iter->pooliter);
+ BLI_mempool_iternew(iter->pooliter.pool, &iter->pooliter);
}
-void *bmiter__vert_of_mesh_step(struct BMIter__vert_of_mesh *iter)
+void *bmiter__elem_of_mesh_step(struct BMIter__elem_of_mesh *iter)
{
#ifdef USE_IMMUTABLE_ASSERT
- BLI_assert(((BMIter *)iter)->count <= iter->bm->totvert);
-#endif
- return BLI_mempool_iterstep(&iter->pooliter);
-}
-
-void bmiter__edge_of_mesh_begin(struct BMIter__edge_of_mesh *iter)
-{
-#ifdef USE_IMMUTABLE_ASSERT
- ((BMIter *)iter)->count = iter->bm->totedge;
-#endif
- BLI_mempool_iternew(iter->bm->epool, &iter->pooliter);
-}
-
-void *bmiter__edge_of_mesh_step(struct BMIter__edge_of_mesh *iter)
-{
-#ifdef USE_IMMUTABLE_ASSERT
- BLI_assert(((BMIter *)iter)->count <= iter->bm->totedge);
-#endif
- return BLI_mempool_iterstep(&iter->pooliter);
-}
-
-void bmiter__face_of_mesh_begin(struct BMIter__face_of_mesh *iter)
-{
-#ifdef USE_IMMUTABLE_ASSERT
- ((BMIter *)iter)->count = iter->bm->totface;
-#endif
- BLI_mempool_iternew(iter->bm->fpool, &iter->pooliter);
-}
-
-void *bmiter__face_of_mesh_step(struct BMIter__face_of_mesh *iter)
-{
-#ifdef USE_IMMUTABLE_ASSERT
- BLI_assert(((BMIter *)iter)->count <= iter->bm->totface);
+ BLI_assert(((BMIter *)iter)->count <= BLI_mempool_count(iter->pooliter.pool));
#endif
return BLI_mempool_iterstep(&iter->pooliter);
}
diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h
index fdf0f27f05f..44be7072e71 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.h
+++ b/source/blender/bmesh/intern/bmesh_iterators.h
@@ -110,16 +110,7 @@ extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX];
for (ele = BM_iter_new(iter, NULL, itype, data), indexvar = 0; ele; ele = BM_iter_step(iter), (indexvar)++)
/* iterator type structs */
-struct BMIter__vert_of_mesh {
- BMesh *bm;
- BLI_mempool_iter pooliter;
-};
-struct BMIter__edge_of_mesh {
- BMesh *bm;
- BLI_mempool_iter pooliter;
-};
-struct BMIter__face_of_mesh {
- BMesh *bm;
+struct BMIter__elem_of_mesh {
BLI_mempool_iter pooliter;
};
struct BMIter__edge_of_vert {
@@ -173,9 +164,7 @@ typedef void *(*BMIter__step_cb) (void *);
typedef struct BMIter {
/* keep union first */
union {
- struct BMIter__vert_of_mesh vert_of_mesh;
- struct BMIter__edge_of_mesh edge_of_mesh;
- struct BMIter__face_of_mesh face_of_mesh;
+ struct BMIter__elem_of_mesh elem_of_mesh;
struct BMIter__edge_of_vert edge_of_vert;
struct BMIter__face_of_vert face_of_vert;
@@ -219,9 +208,7 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, c
void bmiter__##name##_begin(struct BMIter__##name *iter); \
void *bmiter__##name##_step(struct BMIter__##name *iter)
-BMITER_CB_DEF(vert_of_mesh);
-BMITER_CB_DEF(edge_of_mesh);
-BMITER_CB_DEF(face_of_mesh);
+BMITER_CB_DEF(elem_of_mesh);
BMITER_CB_DEF(edge_of_vert);
BMITER_CB_DEF(face_of_vert);
BMITER_CB_DEF(loop_of_vert);
@@ -237,4 +224,12 @@ BMITER_CB_DEF(loop_of_face);
#include "intern/bmesh_iterators_inline.h"
+#define BM_ITER_CHECK_TYPE_DATA(data) \
+ CHECK_TYPE_ANY(data, void *, BMFace *, BMEdge *, BMVert *, BMLoop *, BMElem *)
+
+#define BM_iter_new(iter, bm, itype, data) \
+ (BM_ITER_CHECK_TYPE_DATA(data), BM_iter_new(iter, bm, itype, data))
+#define BM_iter_init(iter, bm, itype, data) \
+ (BM_ITER_CHECK_TYPE_DATA(data), BM_iter_init(iter, bm, itype, data))
+
#endif /* __BMESH_ITERATORS_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_iterators_inline.h b/source/blender/bmesh/intern/bmesh_iterators_inline.h
index b9733d4702f..d3e18b97acb 100644
--- a/source/blender/bmesh/intern/bmesh_iterators_inline.h
+++ b/source/blender/bmesh/intern/bmesh_iterators_inline.h
@@ -60,23 +60,23 @@ BLI_INLINE bool BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *da
case BM_VERTS_OF_MESH:
BLI_assert(bm != NULL);
BLI_assert(data == NULL);
- iter->begin = (BMIter__begin_cb)bmiter__vert_of_mesh_begin;
- iter->step = (BMIter__step_cb)bmiter__vert_of_mesh_step;
- iter->data.vert_of_mesh.bm = bm;
+ iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
+ iter->step = (BMIter__step_cb)bmiter__elem_of_mesh_step;
+ iter->data.elem_of_mesh.pooliter.pool = bm->vpool;
break;
case BM_EDGES_OF_MESH:
BLI_assert(bm != NULL);
BLI_assert(data == NULL);
- iter->begin = (BMIter__begin_cb)bmiter__edge_of_mesh_begin;
- iter->step = (BMIter__step_cb)bmiter__edge_of_mesh_step;
- iter->data.edge_of_mesh.bm = bm;
+ iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
+ iter->step = (BMIter__step_cb)bmiter__elem_of_mesh_step;
+ iter->data.elem_of_mesh.pooliter.pool = bm->epool;
break;
case BM_FACES_OF_MESH:
BLI_assert(bm != NULL);
BLI_assert(data == NULL);
- iter->begin = (BMIter__begin_cb)bmiter__face_of_mesh_begin;
- iter->step = (BMIter__step_cb)bmiter__face_of_mesh_step;
- iter->data.face_of_mesh.bm = bm;
+ iter->begin = (BMIter__begin_cb)bmiter__elem_of_mesh_begin;
+ iter->step = (BMIter__step_cb)bmiter__elem_of_mesh_step;
+ iter->data.elem_of_mesh.pooliter.pool = bm->fpool;
break;
case BM_EDGES_OF_VERT:
BLI_assert(data != NULL);
diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c
index 19e6f646564..ee35d8cd1d2 100644
--- a/source/blender/bmesh/intern/bmesh_marking.c
+++ b/source/blender/bmesh/intern/bmesh_marking.c
@@ -537,7 +537,7 @@ void BM_mesh_select_mode_set(BMesh *bm, int selectmode)
* counts number of elements with flag enabled/disabled
*/
static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag,
- const short respecthide, const bool test_for_enabled)
+ const bool respecthide, const bool test_for_enabled)
{
BMElem *ele;
BMIter iter;
diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c
index 6e8591da0f3..72d25413f09 100644
--- a/source/blender/bmesh/intern/bmesh_mods.c
+++ b/source/blender/bmesh/intern/bmesh_mods.c
@@ -265,7 +265,8 @@ BMFace *BM_faces_join_pair(BMesh *bm, BMFace *f_a, BMFace *f_b, BMEdge *e, const
*
* \param bm The bmesh
* \param f the original face
- * \param v1, v2 vertices which define the split edge, must be different
+ * \param l_a, l_b Loops of this face, their vertices define
+ * the split edge to be created (must be differ and not can't be adjacent in the face).
* \param r_l pointer which will receive the BMLoop for the split edge in the new face
* \param example Edge used for attributes of splitting edge, if non-NULL
* \param nodouble Use an existing edge if found
@@ -348,7 +349,7 @@ BMFace *BM_face_split(BMesh *bm, BMFace *f,
* \param l_a, l_b vertices which define the split edge, must be different
* \param cos Array of coordinates for intermediate points
* \param n Length of \a cos (must be > 0)
- * \param r_l pointer which will receive the BMLoop for the first split edge (from \a v1) in the new face
+ * \param r_l pointer which will receive the BMLoop for the first split edge (from \a l_a) in the new face
* \param example Edge used for attributes of splitting edge, if non-NULL
*
* \return Pointer to the newly created face representing one side of the split
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index d8be55ce7c2..e2be90e7baf 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -104,6 +104,7 @@ static BMOpDefine bmo_smooth_vert_def = {
"smooth_vert",
/* slots_in */
{{"verts", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* input vertices */
+ {"factor", BMO_OP_SLOT_FLT}, /* smoothing factor */
{"mirror_clip_x", BMO_OP_SLOT_BOOL}, /* set vertices close to the x axis before the operation to 0 */
{"mirror_clip_y", BMO_OP_SLOT_BOOL}, /* set vertices close to the y axis before the operation to 0 */
{"mirror_clip_z", BMO_OP_SLOT_BOOL}, /* set vertices close to the z axis before the operation to 0 */
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 9a1914b5596..a8e1acd9c71 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -666,49 +666,25 @@ static bool line_crosses_v2f(const float v1[2], const float v2[2], const float v
*/
bool BM_face_point_inside_test(BMFace *f, const float co[3])
{
- int ax, ay;
- float co2[2], cent[2] = {0.0f, 0.0f}, out[2] = {FLT_MAX * 0.5f, FLT_MAX * 0.5f};
+ float axis_mat[3][3];
+ float (*projverts)[2] = BLI_array_alloca(projverts, f->len);
+
+ float co_2d[2];
BMLoop *l_iter;
- BMLoop *l_first;
- int crosses = 0;
- float onepluseps = 1.0f + (float)FLT_EPSILON * 150.0f;
+ int i;
if (is_zero_v3(f->no))
BM_face_normal_update(f);
-
- /* find best projection of face XY, XZ or YZ: barycentric weights of
- * the 2d projected coords are the same and faster to compute
- *
- * this probably isn't all that accurate, but it has the advantage of
- * being fast (especially compared to projecting into the face orientation)
- */
- axis_dominant_v3(&ax, &ay, f->no);
-
- co2[0] = co[ax];
- co2[1] = co[ay];
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- cent[0] += l_iter->v->co[ax];
- cent[1] += l_iter->v->co[ay];
- } while ((l_iter = l_iter->next) != l_first);
-
- mul_v2_fl(cent, 1.0f / (float)f->len);
-
- l_iter = l_first = BM_FACE_FIRST_LOOP(f);
- do {
- float v1[2], v2[2];
-
- v1[0] = (l_iter->prev->v->co[ax] - cent[0]) * onepluseps + cent[0];
- v1[1] = (l_iter->prev->v->co[ay] - cent[1]) * onepluseps + cent[1];
-
- v2[0] = (l_iter->v->co[ax] - cent[0]) * onepluseps + cent[0];
- v2[1] = (l_iter->v->co[ay] - cent[1]) * onepluseps + cent[1];
-
- crosses += line_crosses_v2f(v1, v2, co2, out) != 0;
- } while ((l_iter = l_iter->next) != l_first);
-
- return crosses % 2 != 0;
+
+ axis_dominant_v3_to_m3(axis_mat, f->no);
+
+ mul_v2_m3v3(co_2d, axis_mat, co);
+
+ for (i = 0, l_iter = BM_FACE_FIRST_LOOP(f); i < f->len; i++, l_iter = l_iter->next) {
+ mul_v2_m3v3(projverts[i], axis_mat, l_iter->v->co);
+ }
+
+ return isect_point_poly_v2(co_2d, (const float (*)[2])projverts, f->len, false);
}
/**
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 685e5443583..40e0356e14c 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -311,7 +311,7 @@ BMLoop *BM_vert_find_first_loop(BMVert *v)
{
BMEdge *e;
- if (!v || !v->e)
+ if (!v->e)
return NULL;
e = bmesh_disk_faceedge_find_first(v->e, v);
diff --git a/source/blender/bmesh/intern/bmesh_structure.c b/source/blender/bmesh/intern/bmesh_structure.c
index d8313dab36f..3e8002c0192 100644
--- a/source/blender/bmesh/intern/bmesh_structure.c
+++ b/source/blender/bmesh/intern/bmesh_structure.c
@@ -108,6 +108,7 @@ bool bmesh_edge_swapverts(BMEdge *e, BMVert *v_orig, BMVert *v_new)
* - #bmesh_radial_append
* - #bmesh_radial_loop_remove
* - #bmesh_radial_facevert_count
+ * - #bmesh_radial_facevert_check
* - #bmesh_radial_faceloop_find_first
* - #bmesh_radial_faceloop_find_next
* - #bmesh_radial_validate
@@ -265,7 +266,7 @@ BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v)
{
const BMEdge *e_find = e;
do {
- if (e_find->l && bmesh_radial_facevert_count(e_find->l, v)) {
+ if (e_find->l && bmesh_radial_facevert_check(e_find->l, v)) {
return (BMEdge *)e_find;
}
} while ((e_find = bmesh_disk_edge_next(e_find, v)) != e);
@@ -275,10 +276,10 @@ BMEdge *bmesh_disk_faceedge_find_first(const BMEdge *e, const BMVert *v)
BMEdge *bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v)
{
- BMEdge *e_find = NULL;
+ BMEdge *e_find;
e_find = bmesh_disk_edge_next(e, v);
do {
- if (e_find->l && bmesh_radial_facevert_count(e_find->l, v)) {
+ if (e_find->l && bmesh_radial_facevert_check(e_find->l, v)) {
return e_find;
}
} while ((e_find = bmesh_disk_edge_next(e_find, v)) != e);
@@ -455,6 +456,24 @@ int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v)
return count;
}
+/**
+ * \brief RADIAL CHECK FACE VERT
+ *
+ * Quicker check for ``bmesh_radial_facevert_count(...) != 0``
+ */
+bool bmesh_radial_facevert_check(const BMLoop *l, const BMVert *v)
+{
+ const BMLoop *l_iter;
+ l_iter = l;
+ do {
+ if (l_iter->v == v) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != l);
+
+ return false;
+}
+
/*****loop cycle functions, e.g. loops surrounding a face**** */
bool bmesh_loop_validate(BMFace *f)
{
diff --git a/source/blender/bmesh/intern/bmesh_structure.h b/source/blender/bmesh/intern/bmesh_structure.h
index d2ad655ae75..29868194bbf 100644
--- a/source/blender/bmesh/intern/bmesh_structure.h
+++ b/source/blender/bmesh/intern/bmesh_structure.h
@@ -61,6 +61,7 @@ void bmesh_radial_loop_remove(BMLoop *l, BMEdge *e) ATTR_NONNULL(1);
* just use member access l->radial_next, l->radial_prev now */
int bmesh_radial_facevert_count(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+bool bmesh_radial_facevert_check(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *bmesh_radial_faceloop_find_next(const BMLoop *l, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
BMLoop *bmesh_radial_faceloop_find_vert(const BMFace *f, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c
index fc507cdbd21..0d9ce4b2731 100644
--- a/source/blender/bmesh/operators/bmo_subdivide.c
+++ b/source/blender/bmesh/operators/bmo_subdivide.c
@@ -32,6 +32,7 @@
#include "BLI_rand.h"
#include "BLI_array.h"
#include "BLI_noise.h"
+#include "BLI_stack.h"
#include "BKE_customdata.h"
@@ -766,8 +767,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BMOpSlot *einput;
const SubDPattern *pat;
SubDParams params;
- SubDFaceData *facedata = NULL;
- BLI_array_declare(facedata);
+ BLI_Stack *facedata;
BMIter viter, fiter, liter;
BMVert *v, **verts = NULL;
BMEdge *edge;
@@ -782,7 +782,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_array_declare(verts);
float smooth, fractal, along_normal;
bool use_sphere, use_single_edge, use_grid_fill, use_only_quads;
- int cornertype, seed, i, j, matched, a, b, numcuts, totesel, smooth_falloff;
+ int cornertype, seed, i, j, a, b, numcuts, totesel, smooth_falloff;
BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, SUBD_SPLIT);
@@ -875,9 +875,12 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BM_EDGE, EDGE_PERCENT);
+ facedata = BLI_stack_new(sizeof(SubDFaceData), __func__);
+
BM_ITER_MESH (face, &fiter, bm, BM_FACES_OF_MESH) {
BMEdge *e1 = NULL, *e2 = NULL;
float vec1[3], vec2[3];
+ bool matched = false;
/* skip non-quads if requested */
if (use_only_quads && face->len != 4)
@@ -891,8 +894,6 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BLI_array_grow_items(edges, face->len);
BLI_array_grow_items(verts, face->len);
- matched = 0;
-
totesel = 0;
BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, i) {
edges[i] = l_new->e;
@@ -930,12 +931,13 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
}
if (matched) {
- BLI_array_grow_one(facedata);
- b = BLI_array_count(facedata) - 1;
- facedata[b].pat = pat;
- facedata[b].start = verts[i];
- facedata[b].face = face;
- facedata[b].totedgesel = totesel;
+ SubDFaceData *fd;
+
+ fd = BLI_stack_push_r(facedata);
+ fd->pat = pat;
+ fd->start = verts[i];
+ fd->face = face;
+ fd->totedgesel = totesel;
BMO_elem_flag_enable(bm, face, SUBD_SPLIT);
break;
}
@@ -966,15 +968,15 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
}
if (matched) {
- BLI_array_grow_one(facedata);
- j = BLI_array_count(facedata) - 1;
+ SubDFaceData *fd;
BMO_elem_flag_enable(bm, face, SUBD_SPLIT);
- facedata[j].pat = pat;
- facedata[j].start = verts[a];
- facedata[j].face = face;
- facedata[j].totedgesel = totesel;
+ fd = BLI_stack_push_r(facedata);
+ fd->pat = pat;
+ fd->start = verts[a];
+ fd->face = face;
+ fd->totedgesel = totesel;
break;
}
}
@@ -982,16 +984,16 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
}
if (!matched && totesel) {
- BLI_array_grow_one(facedata);
- j = BLI_array_count(facedata) - 1;
+ SubDFaceData *fd;
BMO_elem_flag_enable(bm, face, SUBD_SPLIT);
/* must initialize all members here */
- facedata[j].start = NULL;
- facedata[j].pat = NULL;
- facedata[j].totedgesel = totesel;
- facedata[j].face = face;
+ fd = BLI_stack_push_r(facedata);
+ fd->start = NULL;
+ fd->pat = NULL;
+ fd->totedgesel = totesel;
+ fd->face = face;
}
}
@@ -1009,16 +1011,17 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
copy_v3_v3(v->co, co);
}
- i = 0;
- for (i = 0; i < BLI_array_count(facedata); i++) {
- face = facedata[i].face;
+ for (; !BLI_stack_is_empty(facedata); BLI_stack_discard(facedata)) {
+ SubDFaceData *fd = BLI_stack_peek(facedata);
+
+ face = fd->face;
/* figure out which pattern to use */
BLI_array_empty(verts);
- pat = facedata[i].pat;
+ pat = fd->pat;
- if (!pat && facedata[i].totedgesel == 2) {
+ if (!pat && fd->totedgesel == 2) {
int vlen;
/* ok, no pattern. we still may be able to do something */
@@ -1131,7 +1134,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
a = 0;
BM_ITER_ELEM_INDEX (l_new, &liter, face, BM_LOOPS_OF_FACE, j) {
- if (l_new->v == facedata[i].start) {
+ if (l_new->v == fd->start) {
a = j + 1;
break;
}
@@ -1156,7 +1159,7 @@ void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op)
BM_data_layer_free_n(bm, &bm->vdata, CD_SHAPEKEY, params.shape_info.tmpkey);
- if (facedata) BLI_array_free(facedata);
+ BLI_stack_free(facedata);
if (edges) BLI_array_free(edges);
if (verts) BLI_array_free(verts);
BLI_array_free(loops_split);
diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c
index d2d1c0854de..a06d40c8c0f 100644
--- a/source/blender/bmesh/operators/bmo_utils.c
+++ b/source/blender/bmesh/operators/bmo_utils.c
@@ -291,6 +291,7 @@ void bmo_smooth_vert_exec(BMesh *UNUSED(bm), BMOperator *op)
BMEdge *e;
float (*cos)[3] = MEM_mallocN(sizeof(*cos) * BMO_slot_buffer_count(op->slots_in, "verts"), __func__);
float *co, *co2, clip_dist = BMO_slot_float_get(op->slots_in, "clip_dist");
+ const float fac = BMO_slot_float_get(op->slots_in, "factor");
int i, j, clipx, clipy, clipz;
int xaxis, yaxis, zaxis;
@@ -322,7 +323,7 @@ void bmo_smooth_vert_exec(BMesh *UNUSED(bm), BMOperator *op)
}
mul_v3_fl(co, 1.0f / (float)j);
- mid_v3_v3v3(co, co, v->co);
+ interp_v3_v3v3(co, v->co, co, fac);
if (clipx && fabsf(v->co[0]) <= clip_dist)
co[0] = 0.0f;
diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c
index ae9b882cea0..ed9e8783037 100644
--- a/source/blender/bmesh/tools/bmesh_bisect_plane.c
+++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c
@@ -53,7 +53,7 @@
/* -------------------------------------------------------------------- */
/* Math utils */
-static int plane_point_test_v3(const float plane[4], const float co[3], const float eps, float *r_depth)
+static short plane_point_test_v3(const float plane[4], const float co[3], const float eps, float *r_depth)
{
const float f = plane_point_side_v3(plane, co);
*r_depth = f;
@@ -69,7 +69,8 @@ static int plane_point_test_v3(const float plane[4], const float co[3], const fl
* later we may want to move this into some hash lookup
* to a separate struct, but for now we can store in BMesh data */
-#define BM_VERT_DIR(v) ((v)->head.index) /* Direction -1/0/1 */
+#define BM_VERT_DIR(v) ((short *)(&(v)->head.index))[0] /* Direction -1/0/1 */
+#define BM_VERT_SKIP(v) ((short *)(&(v)->head.index))[1] /* Skip Vert 0/1 */
#define BM_VERT_DIST(v) ((v)->no[0]) /* Distance from the plane. */
#define BM_VERT_SORTVAL(v) ((v)->no[1]) /* Temp value for sorting. */
#define BM_VERT_LOOPINDEX(v) /* The verts index within a face (temp var) */ \
@@ -117,6 +118,7 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
STACK_DECLARE(vert_split_arr);
BMLoop *l_iter, *l_first;
bool use_dirs[3] = {false, false, false};
+ bool is_inside = false;
STACK_INIT(vert_split_arr, f_len_orig);
@@ -129,6 +131,11 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
do {
if (vert_is_center_test(l_iter->v)) {
BLI_assert(BM_VERT_DIR(l_iter->v) == 0);
+
+ /* if both are -1 or 1, or both are zero:
+ * don't flip 'inside' var while walking */
+ BM_VERT_SKIP(l_iter->v) = (((BM_VERT_DIR(l_iter->prev->v) ^ BM_VERT_DIR(l_iter->next->v))) == 0);
+
STACK_PUSH(vert_split_arr, l_iter->v);
}
use_dirs[BM_VERT_DIR(l_iter->v) + 1] = true;
@@ -230,15 +237,12 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
for (i = 0; i < STACK_SIZE(vert_split_arr) - 1; i++) {
BMVert *v_a = vert_split_arr[i];
BMVert *v_b = vert_split_arr[i + 1];
- float co_mid[2];
- /* geometric test before doing face lookups,
- * find if the split spans a filled region of the polygon. */
- mid_v2_v2v2(co_mid,
- face_verts_proj_2d[BM_VERT_LOOPINDEX(v_a)],
- face_verts_proj_2d[BM_VERT_LOOPINDEX(v_b)]);
+ if (!BM_VERT_SKIP(v_a)) {
+ is_inside = !is_inside;
+ }
- if (isect_point_poly_v2(co_mid, (const float (*)[2])face_verts_proj_2d, f_len_orig, false)) {
+ if (is_inside) {
BMLoop *l_a, *l_b;
bool found = false;
unsigned int j;
@@ -254,7 +258,8 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
}
}
- BLI_assert(found == true);
+ /* ideally wont happen, but it can for self intersecting faces */
+ // BLI_assert(found == true);
/* in fact this simple test is good enough,
* test if the loops are adjacent */
diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c
new file mode 100644
index 00000000000..050d5ae4808
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_region_match.c
@@ -0,0 +1,1511 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/tools/bmesh_region_match.c
+ * \ingroup bmesh
+ *
+ * Given a contiguous region of faces,
+ * find multiple matching regions (based on topology) and return them.
+ *
+ * Implementation:
+ *
+ * - Given a face region, find its topological center.
+ * - Compare this with other vertices surrounding geometry with this ones.
+ * (reduce the search space by creating a connectivity ID per vertex
+ * and only run comprehensive tests on those).
+ * - All hashes must be order independent so matching topology can be identified.
+ * - The term UUID here doesn't mean each ID is initially unique.
+ * (uniqueness is improved by re-hashing with connected data).
+ */
+
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+#include "BLI_listbase.h"
+#include "BLI_linklist.h"
+#include "BLI_alloca.h"
+#include "BLI_ghash.h"
+#include "BLI_mempool.h"
+#include "BLI_linklist_stack.h"
+
+#include "bmesh.h"
+
+#include "tools/bmesh_region_match.h" /* own incldue */
+
+/* avoid re-creating ghash and pools for each search */
+#define USE_WALKER_REUSE
+
+/* do a first-pass id of all vertices,
+ * this avoids expensive checks on every item later on
+ * (works fine without, just slower) */
+#define USE_PIVOT_FASTMATCH
+
+/* otherwise use active element as pivot, for quick tests only */
+#define USE_PIVOT_SEARCH
+
+// #define DEBUG_TIME
+// #define DEBUG_PRINT
+
+#ifdef DEBUG_TIME
+# include "PIL_time.h"
+# include "PIL_time_utildefines.h"
+#endif
+
+#include "BLI_strict_flags.h"
+
+
+/* -------------------------------------------------------------------- */
+/* UUID-Walk API */
+
+/** \name Internal UUIDWalk API
+ * \{ */
+
+#define PRIME_VERT_INIT 100003
+
+typedef uintptr_t UUID_Int;
+
+typedef struct UUIDWalk {
+
+ /* List of faces we can step onto (UUIDFaceStep's) */
+ ListBase faces_step;
+
+ /* Face & Vert UUID's */
+ GHash *verts_uuid;
+ GHash *faces_uuid;
+
+ /* memory pool for LinkNode's */
+ BLI_mempool *link_pool;
+
+ /* memory pool for LinkBase's */
+ BLI_mempool *lbase_pool;
+
+ /* memory pool for UUIDFaceStep's */
+ BLI_mempool *step_pool;
+ BLI_mempool *step_pool_items;
+
+ /* Optionaly use face-tag to isolate search */
+ bool use_face_isolate;
+
+ /* Increment for each pass added */
+ UUID_Int pass;
+
+ /* runtime vars, aviod re-creating each pass */
+ struct {
+ GHash *verts_uuid; /* BMVert -> UUID */
+ GSet *faces_step; /* BMFace */
+
+ GHash *faces_from_uuid; /* UUID -> UUIDFaceStepItem */
+
+ UUID_Int *rehash_store;
+ unsigned int rehash_store_len;
+ } cache;
+
+} UUIDWalk;
+
+/* stores a set of potential faces to step onto */
+typedef struct UUIDFaceStep {
+ struct UUIDFaceStep *next, *prev;
+
+ /* unsorted 'BMFace' */
+ LinkNode *faces;
+
+ /* faces sorted into 'UUIDFaceStepItem' */
+ ListBase items;
+} UUIDFaceStep;
+
+/* store face-lists with same uuid */
+typedef struct UUIDFaceStepItem {
+ struct UUIDFaceStepItem *next, *prev;
+ uintptr_t uuid;
+
+ LinkNode *list;
+ unsigned int list_len;
+} UUIDFaceStepItem;
+
+BLI_INLINE bool bm_uuidwalk_face_test(
+ UUIDWalk *uuidwalk, BMFace *f)
+{
+ if (uuidwalk->use_face_isolate) {
+ return BM_elem_flag_test_bool(f, BM_ELEM_TAG);
+ }
+ else {
+ return true;
+ }
+}
+
+BLI_INLINE bool bm_uuidwalk_vert_lookup(
+ UUIDWalk *uuidwalk, BMVert *v, UUID_Int *r_uuid)
+{
+ void **ret;
+ ret = BLI_ghash_lookup_p(uuidwalk->verts_uuid, v);
+ if (ret) {
+ *r_uuid = (UUID_Int)(*ret);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+BLI_INLINE bool bm_uuidwalk_face_lookup(
+ UUIDWalk *uuidwalk, BMFace *f, UUID_Int *r_uuid)
+{
+ void **ret;
+ ret = BLI_ghash_lookup_p(uuidwalk->faces_uuid, f);
+ if (ret) {
+ *r_uuid = (UUID_Int)(*ret);
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+static unsigned int ghashutil_bmelem_indexhash(const void *key)
+{
+ const BMElem *ele = key;
+ return (unsigned int)BM_elem_index_get(ele);
+}
+
+static bool ghashutil_bmelem_indexcmp(const void *a, const void *b)
+{
+ BLI_assert((a != b) == (BM_elem_index_get((BMElem *)a) != BM_elem_index_get((BMElem *)b)));
+ return (a != b);
+}
+
+static GHash *ghash_bmelem_new_ex(const char *info,
+ const unsigned int nentries_reserve)
+{
+ return BLI_ghash_new_ex(ghashutil_bmelem_indexhash, ghashutil_bmelem_indexcmp, info, nentries_reserve);
+}
+
+static GSet *gset_bmelem_new_ex(const char *info,
+ const unsigned int nentries_reserve)
+{
+ return BLI_gset_new_ex(ghashutil_bmelem_indexhash, ghashutil_bmelem_indexcmp, info, nentries_reserve);
+}
+
+
+static GHash *ghash_bmelem_new(const char *info)
+{
+ return ghash_bmelem_new_ex(info, 0);
+}
+
+static GSet *gset_bmelem_new(const char *info)
+{
+ return gset_bmelem_new_ex(info, 0);
+}
+
+
+static void bm_uuidwalk_init(
+ UUIDWalk *uuidwalk,
+ const unsigned int faces_src_region_len,
+ const unsigned int verts_src_region_len)
+{
+ BLI_listbase_clear(&uuidwalk->faces_step);
+
+ uuidwalk->verts_uuid = ghash_bmelem_new_ex(__func__, verts_src_region_len);
+ uuidwalk->faces_uuid = ghash_bmelem_new_ex(__func__, faces_src_region_len);
+
+ uuidwalk->cache.verts_uuid = ghash_bmelem_new(__func__);
+ uuidwalk->cache.faces_step = gset_bmelem_new(__func__);
+
+ /* works because 'int' ghash works for intptr_t too */
+ uuidwalk->cache.faces_from_uuid = BLI_ghash_int_new(__func__);
+
+ uuidwalk->cache.rehash_store = NULL;
+ uuidwalk->cache.rehash_store_len = 0;
+
+ uuidwalk->use_face_isolate = false;
+
+ /* smaller pool's for faster clearing */
+ uuidwalk->link_pool = BLI_mempool_create(sizeof(LinkNode), 64, 64, BLI_MEMPOOL_NOP);
+ uuidwalk->step_pool = BLI_mempool_create(sizeof(UUIDFaceStep), 64, 64, BLI_MEMPOOL_NOP);
+ uuidwalk->step_pool_items = BLI_mempool_create(sizeof(UUIDFaceStepItem), 64, 64, BLI_MEMPOOL_NOP);
+
+ uuidwalk->pass = 1;
+}
+
+static void bm_uuidwalk_clear(
+ UUIDWalk *uuidwalk)
+{
+ BLI_listbase_clear(&uuidwalk->faces_step);
+
+ BLI_ghash_clear(uuidwalk->verts_uuid, NULL, NULL);
+ BLI_ghash_clear(uuidwalk->faces_uuid, NULL, NULL);
+
+ BLI_ghash_clear(uuidwalk->cache.verts_uuid, NULL, NULL);
+ BLI_gset_clear(uuidwalk->cache.faces_step, NULL);
+ BLI_ghash_clear(uuidwalk->cache.faces_from_uuid, NULL, NULL);
+
+ /* keep rehash_store as-is, for reuse */
+
+ uuidwalk->use_face_isolate = false;
+
+ BLI_mempool_clear(uuidwalk->link_pool);
+ BLI_mempool_clear(uuidwalk->step_pool);
+ BLI_mempool_clear(uuidwalk->step_pool_items);
+
+ uuidwalk->pass = 1;
+}
+
+static void bm_uuidwalk_free(
+ UUIDWalk *uuidwalk)
+{
+ /**
+ * Handled by pools
+ *
+ * - uuidwalk->faces_step
+ */
+
+ BLI_ghash_free(uuidwalk->verts_uuid, NULL, NULL);
+ BLI_ghash_free(uuidwalk->faces_uuid, NULL, NULL);
+
+ /* cache */
+ BLI_ghash_free(uuidwalk->cache.verts_uuid, NULL, NULL);
+ BLI_gset_free(uuidwalk->cache.faces_step, NULL);
+ BLI_ghash_free(uuidwalk->cache.faces_from_uuid, NULL, NULL);
+ MEM_SAFE_FREE(uuidwalk->cache.rehash_store);
+
+ BLI_mempool_destroy(uuidwalk->link_pool);
+ BLI_mempool_destroy(uuidwalk->step_pool);
+ BLI_mempool_destroy(uuidwalk->step_pool_items);
+}
+
+static UUID_Int bm_uuidwalk_calc_vert_uuid(
+ UUIDWalk *uuidwalk, BMVert *v)
+{
+#define PRIME_VERT_SMALL 7
+#define PRIME_VERT_MID 43
+#define PRIME_VERT_LARGE 1031
+
+#define PRIME_FACE_SMALL 13
+#define PRIME_FACE_MID 53
+
+ UUID_Int uuid;
+
+ uuid = uuidwalk->pass * PRIME_VERT_LARGE;
+
+ /* vert -> other */
+ {
+ unsigned int tot = 0;
+ BMIter eiter;
+ BMEdge *e;
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ BMVert *v_other = BM_edge_other_vert(e, v);
+ UUID_Int uuid_other;
+ if (bm_uuidwalk_vert_lookup(uuidwalk, v_other, &uuid_other)) {
+ uuid ^= (uuid_other * PRIME_VERT_SMALL);
+ tot += 1;
+ }
+ }
+ uuid ^= (tot * PRIME_VERT_MID);
+ }
+
+ /* faces */
+ {
+ unsigned int tot = 0;
+ BMIter iter;
+ BMFace *f;
+
+ BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
+ UUID_Int uuid_other;
+ if (bm_uuidwalk_face_lookup(uuidwalk, f, &uuid_other)) {
+ uuid ^= (uuid_other * PRIME_FACE_SMALL);
+ tot += 1;
+ }
+ }
+ uuid ^= (tot * PRIME_FACE_MID);
+ }
+
+ return uuid;
+
+#undef PRIME_VERT_SMALL
+#undef PRIME_VERT_MID
+#undef PRIME_VERT_LARGE
+
+#undef PRIME_FACE_SMALL
+#undef PRIME_FACE_MID
+}
+
+static UUID_Int bm_uuidwalk_calc_face_uuid(
+ UUIDWalk *uuidwalk, BMFace *f)
+{
+#define PRIME_VERT_SMALL 11
+
+#define PRIME_FACE_SMALL 17
+#define PRIME_FACE_LARGE 1013
+
+ UUID_Int uuid;
+
+ uuid = uuidwalk->pass * (unsigned int)f->len * PRIME_FACE_LARGE;
+
+ /* face-verts */
+ {
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ UUID_Int uuid_other;
+ if (bm_uuidwalk_vert_lookup(uuidwalk, l_iter->v, &uuid_other)) {
+ uuid ^= (uuid_other * PRIME_VERT_SMALL);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ /* face-faces (connected by edge) */
+ {
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (l_iter->radial_next != l_iter) {
+ BMLoop *l_iter_radial = l_iter->radial_next;
+ do {
+ UUID_Int uuid_other;
+ if (bm_uuidwalk_face_lookup(uuidwalk, l_iter_radial->f, &uuid_other)) {
+ uuid ^= (uuid_other * PRIME_FACE_SMALL);
+ }
+ } while ((l_iter_radial = l_iter_radial->radial_next) != l_iter);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ return uuid;
+
+#undef PRIME_VERT_SMALL
+
+#undef PRIME_FACE_SMALL
+#undef PRIME_FACE_LARGE
+}
+
+static void bm_uuidwalk_rehash_reserve(
+ UUIDWalk *uuidwalk, unsigned int rehash_store_len_new)
+{
+ if (UNLIKELY(rehash_store_len_new > uuidwalk->cache.rehash_store_len)) {
+ /* avoid re-allocs */
+ rehash_store_len_new *= 2;
+ uuidwalk->cache.rehash_store =
+ MEM_reallocN(uuidwalk->cache.rehash_store,
+ rehash_store_len_new * sizeof(*uuidwalk->cache.rehash_store));
+ uuidwalk->cache.rehash_store_len = rehash_store_len_new;
+ }
+}
+
+/**
+ * Re-hash all elements, delay updating so as not to create feedback loop.
+ */
+static void bm_uuidwalk_rehash(
+ UUIDWalk *uuidwalk)
+{
+ GHashIterator gh_iter;
+ UUID_Int *uuid_store;
+ unsigned int i;
+
+ unsigned int rehash_store_len_new = (unsigned int)MAX2(BLI_ghash_size(uuidwalk->verts_uuid),
+ BLI_ghash_size(uuidwalk->faces_uuid));
+
+ bm_uuidwalk_rehash_reserve(uuidwalk, rehash_store_len_new);
+ uuid_store = uuidwalk->cache.rehash_store;
+
+ /* verts */
+ i = 0;
+ GHASH_ITER (gh_iter, uuidwalk->verts_uuid) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ uuid_store[i++] = bm_uuidwalk_calc_vert_uuid(uuidwalk, v);
+ }
+ i = 0;
+ GHASH_ITER (gh_iter, uuidwalk->verts_uuid) {
+ void **uuid_p = BLI_ghashIterator_getValue_p(&gh_iter);
+ *((UUID_Int *)uuid_p) = uuid_store[i++];
+ }
+
+ /* faces */
+ i = 0;
+ GHASH_ITER (gh_iter, uuidwalk->faces_uuid) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ uuid_store[i++] = bm_uuidwalk_calc_face_uuid(uuidwalk, f);
+ }
+ i = 0;
+ GHASH_ITER (gh_iter, uuidwalk->faces_uuid) {
+ void **uuid_p = BLI_ghashIterator_getValue_p(&gh_iter);
+ *((UUID_Int *)uuid_p) = uuid_store[i++];
+ }
+}
+
+static void bm_uuidwalk_rehash_facelinks(
+ UUIDWalk *uuidwalk,
+ LinkNode *faces, const unsigned int faces_len,
+ const bool is_init)
+{
+ UUID_Int *uuid_store;
+ LinkNode *f_link;
+ unsigned int i;
+
+ bm_uuidwalk_rehash_reserve(uuidwalk, faces_len);
+ uuid_store = uuidwalk->cache.rehash_store;
+
+ i = 0;
+ for (f_link = faces; f_link; f_link = f_link->next) {
+ BMFace *f = f_link->link;
+ uuid_store[i++] = bm_uuidwalk_calc_face_uuid(uuidwalk, f);
+ }
+
+ i = 0;
+ if (is_init) {
+ for (f_link = faces; f_link; f_link = f_link->next) {
+ BMFace *f = f_link->link;
+ BLI_ghash_insert(uuidwalk->faces_uuid, f, (void *)uuid_store[i++]);
+ }
+ }
+ else {
+ for (f_link = faces; f_link; f_link = f_link->next) {
+ BMFace *f = f_link->link;
+ void **uuid_p = BLI_ghash_lookup_p(uuidwalk->faces_uuid, f);
+ *((UUID_Int *)uuid_p) = uuid_store[i++];
+ }
+ }
+}
+
+static bool bm_vert_is_uuid_connect(
+ UUIDWalk *uuidwalk, BMVert *v)
+{
+ BMIter eiter;
+ BMEdge *e;
+
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ BMVert *v_other = BM_edge_other_vert(e, v);
+ if (BLI_ghash_haskey(uuidwalk->verts_uuid, v_other)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+static void bm_uuidwalk_pass_add(
+ UUIDWalk *uuidwalk, LinkNode *faces_pass, const unsigned int faces_pass_len)
+{
+ GHashIterator gh_iter;
+ GHash *verts_uuid_pass;
+ GSet *faces_step_next;
+ LinkNode *f_link;
+
+ UUIDFaceStep *fstep;
+
+ BLI_assert(faces_pass_len == (unsigned int)BLI_linklist_length(faces_pass));
+
+ /* rehash faces now all their verts have been added */
+ bm_uuidwalk_rehash_facelinks(uuidwalk, faces_pass, faces_pass_len, true);
+
+ /* create verts_new */
+ verts_uuid_pass = uuidwalk->cache.verts_uuid;
+ faces_step_next = uuidwalk->cache.faces_step;
+
+ BLI_assert(BLI_ghash_size(verts_uuid_pass) == 0);
+ BLI_assert(BLI_gset_size(faces_step_next) == 0);
+
+ /* Add the face_step data from connected faces, creating new passes */
+ fstep = BLI_mempool_alloc(uuidwalk->step_pool);
+ BLI_addhead(&uuidwalk->faces_step, fstep);
+ fstep->faces = NULL;
+ BLI_listbase_clear(&fstep->items);
+
+ for (f_link = faces_pass; f_link; f_link = f_link->next) {
+ BMFace *f = f_link->link;
+ BMLoop *l_iter, *l_first;
+
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ /* fill verts_new */
+ if (!BLI_ghash_haskey(uuidwalk->verts_uuid, l_iter->v) &&
+ !BLI_ghash_haskey(verts_uuid_pass, l_iter->v) &&
+ (bm_vert_is_uuid_connect(uuidwalk, l_iter->v) == true))
+ {
+ const UUID_Int uuid = bm_uuidwalk_calc_vert_uuid(uuidwalk, l_iter->v);
+ BLI_ghash_insert(verts_uuid_pass, l_iter->v, (void *)uuid);
+ }
+
+ /* fill faces_step_next */
+ if (l_iter->radial_next != l_iter) {
+ BMLoop *l_iter_radial = l_iter->radial_next;
+ do {
+ if (!BLI_ghash_haskey(uuidwalk->faces_uuid, l_iter_radial->f) &&
+ !BLI_gset_haskey(faces_step_next, l_iter_radial->f) &&
+ (bm_uuidwalk_face_test(uuidwalk, l_iter_radial->f)))
+ {
+ BLI_gset_insert(faces_step_next, l_iter_radial->f);
+
+ /* add to fstep */
+ BLI_linklist_prepend_pool(&fstep->faces, l_iter_radial->f, uuidwalk->link_pool);
+ }
+ } while ((l_iter_radial = l_iter_radial->radial_next) != l_iter);
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ /* faces_uuid.update(verts_new) */
+ GHASH_ITER (gh_iter, verts_uuid_pass) {
+ BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
+ void *uuid_p = BLI_ghashIterator_getValue(&gh_iter);
+ BLI_ghash_insert(uuidwalk->verts_uuid, v, uuid_p);
+ }
+
+ /* rehash faces now all their verts have been added */
+ bm_uuidwalk_rehash_facelinks(uuidwalk, faces_pass, faces_pass_len, false);
+
+ uuidwalk->pass += 1;
+
+ BLI_ghash_clear(uuidwalk->cache.verts_uuid, NULL, NULL);
+ BLI_gset_clear(uuidwalk->cache.faces_step, NULL);
+}
+
+static int bm_face_len_cmp(const void *v1, const void *v2)
+{
+ const BMFace *f1 = v1, *f2 = v2;
+
+ if (f1->len > f2->len) return 1;
+ else if (f1->len < f2->len) return -1;
+ else return 0;
+}
+
+static unsigned int bm_uuidwalk_init_from_edge(
+ UUIDWalk *uuidwalk, BMEdge *e)
+{
+ BMLoop *l_iter = e->l;
+ unsigned int f_arr_len = (unsigned int)BM_edge_face_count(e);
+ BMFace **f_arr = BLI_array_alloca(f_arr, f_arr_len);
+ unsigned int fstep_num = 0, i = 0;
+
+ do {
+ BMFace *f = l_iter->f;
+ if (bm_uuidwalk_face_test(uuidwalk, f)) {
+ f_arr[i++] = f;
+ }
+ } while ((l_iter = l_iter->radial_next) != e->l);
+ BLI_assert(i <= f_arr_len);
+ f_arr_len = i;
+
+ qsort(f_arr, f_arr_len, sizeof(*f_arr), bm_face_len_cmp);
+
+ /* start us off! */
+ {
+ const UUID_Int uuid = PRIME_VERT_INIT;
+ BLI_ghash_insert(uuidwalk->verts_uuid, e->v1, (void *)uuid);
+ BLI_ghash_insert(uuidwalk->verts_uuid, e->v2, (void *)uuid);
+ }
+
+ /* turning an array into LinkNode's seems odd,
+ * but this is just for initialization,
+ * elsewhere using LinkNode's makes more sense */
+ for (i = 0; i < f_arr_len; i++) {
+ LinkNode *faces_pass = NULL;
+ const int f_len = f_arr[i]->len;
+
+ do {
+ BLI_linklist_prepend_pool(&faces_pass, f_arr[i++], uuidwalk->link_pool);
+ } while (i < f_arr_len && (f_len == f_arr[i]->len));
+
+ bm_uuidwalk_pass_add(uuidwalk, faces_pass, i);
+ BLI_linklist_free_pool(faces_pass, NULL, uuidwalk->link_pool);
+ fstep_num += 1;
+ }
+
+ return fstep_num;
+}
+
+#undef PRIME_VERT_INIT
+
+/** \} */
+
+
+/** \name Internal UUIDFaceStep API
+ * \{ */
+
+static int facestep_sort(const void *a, const void *b)
+{
+ const UUIDFaceStepItem *fstep_a = a;
+ const UUIDFaceStepItem *fstep_b = b;
+ return (fstep_a->uuid > fstep_b->uuid) ? 1 : 0;
+}
+
+/**
+ * Put faces in lists based on their uuid's,
+ * re-run for each pass since rehashing may differentiate face-groups.
+ */
+static bool bm_uuidwalk_facestep_begin(
+ UUIDWalk *uuidwalk, UUIDFaceStep *fstep)
+{
+ LinkNode *f_link, *f_link_next, **f_link_prev_p;
+ bool ok = false;
+
+ BLI_assert(BLI_ghash_size(uuidwalk->cache.faces_from_uuid) == 0);
+ BLI_assert(BLI_countlist(&fstep->items) == 0);
+
+ f_link_prev_p = &fstep->faces;
+ for (f_link = fstep->faces; f_link; f_link = f_link_next) {
+ BMFace *f = f_link->link;
+ f_link_next = f_link->next;
+
+ /* possible another pass added this face already, free in that case */
+ if (!BLI_ghash_haskey(uuidwalk->faces_uuid, f)) {
+ const UUID_Int uuid = bm_uuidwalk_calc_face_uuid(uuidwalk, f);
+ UUIDFaceStepItem *fstep_item;
+
+ ok = true;
+
+ fstep_item = BLI_ghash_lookup(uuidwalk->cache.faces_from_uuid, (void *)uuid);
+ if (UNLIKELY(fstep_item == NULL)) {
+ fstep_item = BLI_mempool_alloc(uuidwalk->step_pool_items);
+ BLI_ghash_insert(uuidwalk->cache.faces_from_uuid, (void *)uuid, fstep_item);
+
+ /* add to start, so its handled on the next round of passes */
+ BLI_addhead(&fstep->items, fstep_item);
+ fstep_item->uuid = uuid;
+ fstep_item->list = NULL;
+ fstep_item->list_len = 0;
+ }
+
+ BLI_linklist_prepend_pool(&fstep_item->list, f, uuidwalk->link_pool);
+ fstep_item->list_len += 1;
+
+ f_link_prev_p = &f_link->next;
+ }
+ else {
+ *f_link_prev_p = f_link->next;
+ BLI_mempool_free(uuidwalk->link_pool, f_link);
+ }
+ }
+
+ BLI_ghash_clear(uuidwalk->cache.faces_from_uuid, NULL, NULL);
+
+ BLI_sortlist(&fstep->items, facestep_sort);
+
+ return ok;
+}
+
+/**
+ * Cleans up temp data from #bm_uuidwalk_facestep_begin
+ */
+static void bm_uuidwalk_facestep_end(
+ UUIDWalk *uuidwalk, UUIDFaceStep *fstep)
+{
+ UUIDFaceStepItem *fstep_item;
+
+ while ((fstep_item = BLI_pophead(&fstep->items))) {
+ BLI_mempool_free(uuidwalk->step_pool_items, fstep_item);
+ }
+}
+
+static void bm_uuidwalk_facestep_free(
+ UUIDWalk *uuidwalk, UUIDFaceStep *fstep)
+{
+ LinkNode *f_link, *f_link_next;
+
+ BLI_assert(BLI_listbase_is_empty(&fstep->items));
+
+ for (f_link = fstep->faces; f_link; f_link = f_link_next) {
+ f_link_next = f_link->next;
+ BLI_mempool_free(uuidwalk->link_pool, f_link);
+ }
+
+ BLI_remlink(&uuidwalk->faces_step, fstep);
+ BLI_mempool_free(uuidwalk->step_pool, fstep);
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+/* Main Loop to match up regions */
+
+/**
+ * Given a face region and 2 candidate verts to begin mapping.
+ * return the matching region or NULL.
+ */
+static BMFace **bm_mesh_region_match_pair(
+#ifdef USE_WALKER_REUSE
+ UUIDWalk *w_src, UUIDWalk *w_dst,
+#endif
+ BMEdge *e_src, BMEdge *e_dst,
+ const unsigned int faces_src_region_len,
+ const unsigned int verts_src_region_len,
+ unsigned int *r_faces_result_len)
+{
+#ifndef USE_WALKER_REUSE
+ UUIDWalk w_src_, w_dst_;
+ UUIDWalk *w_src = &w_src_, *w_dst = &w_dst_;
+#endif
+ BMFace **faces_result = NULL;
+ bool found = false;
+
+ BLI_assert(e_src != e_dst);
+
+#ifndef USE_WALKER_REUSE
+ bm_uuidwalk_init(w_src, faces_src_region_len, verts_src_region_len);
+ bm_uuidwalk_init(w_dst, faces_src_region_len, verts_src_region_len);
+#endif
+
+ w_src->use_face_isolate = true;
+
+ /* setup the initial state */
+ if (UNLIKELY(bm_uuidwalk_init_from_edge(w_src, e_src) !=
+ bm_uuidwalk_init_from_edge(w_dst, e_dst)))
+ {
+ /* should never happen, if verts passed are compatible, but to be safe... */
+ goto finally;
+ }
+
+ bm_uuidwalk_rehash_reserve(w_src, MAX2(faces_src_region_len, verts_src_region_len));
+ bm_uuidwalk_rehash_reserve(w_dst, MAX2(faces_src_region_len, verts_src_region_len));
+
+ while (true) {
+ bool ok = false;
+
+ UUIDFaceStep *fstep_src = w_src->faces_step.first;
+ UUIDFaceStep *fstep_dst = w_dst->faces_step.first;
+
+ BLI_assert(BLI_countlist(&w_src->faces_step) == BLI_countlist(&w_dst->faces_step));
+
+ while (fstep_src) {
+
+ /* even if the destination has faces,
+ * it's not important, since the source doesn't, free and move-on. */
+ if (fstep_src->faces == NULL) {
+ UUIDFaceStep *fstep_src_next = fstep_src->next;
+ UUIDFaceStep *fstep_dst_next = fstep_dst->next;
+ bm_uuidwalk_facestep_free(w_src, fstep_src);
+ bm_uuidwalk_facestep_free(w_dst, fstep_dst);
+ fstep_src = fstep_src_next;
+ fstep_dst = fstep_dst_next;
+ continue;
+ }
+
+ if (bm_uuidwalk_facestep_begin(w_src, fstep_src) &&
+ bm_uuidwalk_facestep_begin(w_dst, fstep_dst))
+ {
+ /* Step over face-lists with matching UUID's
+ * both lists are sorted, so no need for lookups.
+ * The data is created on 'begin' and cleared on 'end' */
+ UUIDFaceStepItem *fstep_item_src;
+ UUIDFaceStepItem *fstep_item_dst;
+ for (fstep_item_src = fstep_src->items.first,
+ fstep_item_dst = fstep_dst->items.first;
+ fstep_item_src && fstep_item_dst;
+ fstep_item_src = fstep_item_src->next,
+ fstep_item_dst = fstep_item_dst->next)
+ {
+ while ((fstep_item_dst != NULL) &&
+ (fstep_item_dst->uuid < fstep_item_src->uuid))
+ {
+ fstep_item_dst = fstep_item_dst->next;
+ }
+
+ if ((fstep_item_dst == NULL) ||
+ (fstep_item_src->uuid != fstep_item_dst->uuid) ||
+ (fstep_item_src->list_len > fstep_item_dst->list_len))
+ {
+ /* if the target walker has less than the source
+ * then the islands don't match, bail early */
+ ok = false;
+ break;
+ }
+
+ if (fstep_item_src->list_len == fstep_item_dst->list_len) {
+ /* found a match */
+ bm_uuidwalk_pass_add(w_src, fstep_item_src->list, fstep_item_src->list_len);
+ bm_uuidwalk_pass_add(w_dst, fstep_item_dst->list, fstep_item_dst->list_len);
+
+ BLI_linklist_free_pool(fstep_item_src->list, NULL, w_src->link_pool);
+ BLI_linklist_free_pool(fstep_item_dst->list, NULL, w_dst->link_pool);
+
+ fstep_item_src->list = NULL;
+ fstep_item_src->list_len = 0;
+
+ fstep_item_dst->list = NULL;
+ fstep_item_dst->list_len = 0;
+
+ ok = true;
+ }
+ }
+ }
+
+ bm_uuidwalk_facestep_end(w_src, fstep_src);
+ bm_uuidwalk_facestep_end(w_dst, fstep_dst);
+
+ /* lock-step */
+ fstep_src = fstep_src->next;
+ fstep_dst = fstep_dst->next;
+ }
+
+ if (!ok) {
+ break;
+ }
+
+ found = ((unsigned int)BLI_ghash_size(w_dst->faces_uuid) == faces_src_region_len);
+ if (found) {
+ break;
+ }
+
+ /* Expensive! but some cases fails without.
+ * (also faster in other cases since it can rule-out invalid regions) */
+ bm_uuidwalk_rehash(w_src);
+ bm_uuidwalk_rehash(w_dst);
+ }
+
+ if (found) {
+ GHashIterator gh_iter;
+ const unsigned int faces_result_len = (unsigned int)BLI_ghash_size(w_dst->faces_uuid);
+ unsigned int i;
+
+ faces_result = MEM_mallocN(sizeof(faces_result) * (faces_result_len + 1), __func__);
+ GHASH_ITER_INDEX (gh_iter, w_dst->faces_uuid, i) {
+ BMFace *f = BLI_ghashIterator_getKey(&gh_iter);
+ faces_result[i] = f;
+ }
+ faces_result[faces_result_len] = NULL;
+ *r_faces_result_len = faces_result_len;
+ }
+ else {
+ *r_faces_result_len = 0;
+ }
+
+finally:
+
+#ifdef USE_WALKER_REUSE
+ bm_uuidwalk_clear(w_src);
+ bm_uuidwalk_clear(w_dst);
+#else
+ bm_uuidwalk_free(w_src);
+ bm_uuidwalk_free(w_dst);
+#endif
+
+ return faces_result;
+}
+
+/**
+ * Tag as visited, avoid re-use.
+ */
+static void bm_face_array_visit(
+ BMFace **faces, const unsigned int faces_len,
+ unsigned int *r_verts_len,
+ bool visit_faces)
+{
+ unsigned int verts_len = 0;
+ unsigned int i;
+ for (i = 0; i < faces_len; i++) {
+ BMFace *f = faces[i];
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ if (r_verts_len) {
+ if (!BM_elem_flag_test(l_iter->v, BM_ELEM_TAG)) {
+ verts_len += 1;
+ }
+ }
+
+ BM_elem_flag_enable(l_iter->e, BM_ELEM_TAG);
+ BM_elem_flag_enable(l_iter->v, BM_ELEM_TAG);
+ } while ((l_iter = l_iter->next) != l_first);
+
+ if (visit_faces) {
+ BM_elem_flag_enable(f, BM_ELEM_TAG);
+ }
+ }
+
+ if (r_verts_len) {
+ *r_verts_len = verts_len;
+ }
+}
+
+#ifdef USE_PIVOT_SEARCH
+
+/** \name Internal UUIDWalk API
+ * \{ */
+
+/* signed user id */
+typedef intptr_t SUID_Int;
+
+static bool bm_edge_is_region_boundary(BMEdge *e)
+{
+ if (e->l->radial_next != e->l) {
+ BMLoop *l_iter = e->l;
+ do {
+ if (!BM_elem_flag_test(l_iter->f, BM_ELEM_TAG)) {
+ return true;
+ }
+ } while ((l_iter = l_iter->radial_next) != e->l);
+ return false;
+ }
+ else {
+ /* boundary */
+ return true;
+ }
+}
+
+static void bm_face_region_pivot_edge_use_best(
+ GHash *gh, BMEdge *e_test,
+ BMEdge **r_e_pivot_best,
+ SUID_Int e_pivot_best_id[2])
+{
+ SUID_Int e_pivot_test_id[2];
+
+ e_pivot_test_id[0] = (SUID_Int)BLI_ghash_lookup(gh, e_test->v1);
+ e_pivot_test_id[1] = (SUID_Int)BLI_ghash_lookup(gh, e_test->v2);
+ if (e_pivot_test_id[0] > e_pivot_test_id[1]) {
+ SWAP(SUID_Int, e_pivot_test_id[0], e_pivot_test_id[1]);
+ }
+
+ if ((*r_e_pivot_best == NULL) ||
+ ((e_pivot_best_id[0] != e_pivot_test_id[0]) ?
+ (e_pivot_best_id[0] < e_pivot_test_id[0]) :
+ (e_pivot_best_id[1] < e_pivot_test_id[1])))
+ {
+ e_pivot_best_id[0] = e_pivot_test_id[0];
+ e_pivot_best_id[1] = e_pivot_test_id[1];
+
+ /* both verts are from the same pass, record this! */
+ *r_e_pivot_best = e_test;
+ }
+}
+
+/* quick id from a boundary vertex */
+static SUID_Int bm_face_region_vert_boundary_id(BMVert *v)
+{
+#define PRIME_VERT_SMALL_A 7
+#define PRIME_VERT_SMALL_B 13
+#define PRIME_VERT_MID_A 103
+#define PRIME_VERT_MID_B 131
+
+ int tot = 0;
+ BMIter iter;
+ BMLoop *l;
+ SUID_Int id = PRIME_VERT_MID_A;
+
+ BM_ITER_ELEM (l, &iter, v, BM_LOOPS_OF_VERT) {
+ const bool is_boundary_vert = (bm_edge_is_region_boundary(l->e) || bm_edge_is_region_boundary(l->prev->e));
+ id ^= l->f->len * (is_boundary_vert ? PRIME_VERT_SMALL_A : PRIME_VERT_SMALL_B);
+ tot += 1;
+ }
+
+ id ^= (tot * PRIME_VERT_MID_B);
+
+ return id ? ABS(id) : 1;
+
+#undef PRIME_VERT_SMALL_A
+#undef PRIME_VERT_SMALL_B
+#undef PRIME_VERT_MID_A
+#undef PRIME_VERT_MID_B
+}
+
+/**
+ * Accumulate id's from a previous pass (swap sign each pass)
+ */
+static SUID_Int bm_face_region_vert_pass_id(GHash *gh, BMVert *v)
+{
+ BMIter eiter;
+ BMEdge *e;
+ SUID_Int tot = 0;
+ SUID_Int v_sum_face_len = 0;
+ SUID_Int v_sum_id = 0;
+ SUID_Int id;
+ SUID_Int id_min = INTPTR_MIN + 1;
+
+#define PRIME_VERT_MID_A 23
+#define PRIME_VERT_MID_B 31
+
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ BMVert *v_other = BM_edge_other_vert(e, v);
+ if (BM_elem_flag_test(v_other, BM_ELEM_TAG)) {
+ /* non-zero values aren't allowed... so no need to check haskey */
+ SUID_Int v_other_id = (SUID_Int)BLI_ghash_lookup(gh, v_other);
+ if (v_other_id > 0) {
+ v_sum_id += v_other_id;
+ tot += 1;
+
+ /* face-count */
+ {
+ BMLoop *l_iter = e->l;
+ do {
+ if (BM_elem_flag_test(l_iter->f, BM_ELEM_TAG)) {
+ v_sum_face_len += l_iter->f->len;
+ }
+ } while ((l_iter = l_iter->radial_next) != e->l);
+ }
+ }
+ }
+ }
+ }
+
+ id = (tot * PRIME_VERT_MID_A);
+ id ^= (v_sum_face_len * PRIME_VERT_MID_B);
+ id ^= v_sum_id;
+
+ /* disallow 0 & min (since it can't be flipped) */
+ id = (UNLIKELY(id == 0) ? 1 : UNLIKELY(id < id_min) ? id_min : id);
+
+ return ABS(id);
+
+#undef PRIME_VERT_MID_A
+#undef PRIME_VERT_MID_B
+}
+
+/**
+ * Take a face region and find the inner-most vertex.
+ * also calculate the number of connections to the boundary,
+ * and the total number unique of verts used by this face region.
+ *
+ * This is only called once on the source region (no need to be highly optimized).
+ */
+static BMEdge *bm_face_region_pivot_edge_find(
+ BMFace **faces_region, unsigned int faces_region_len,
+ unsigned int verts_region_len,
+ unsigned int *r_depth)
+{
+ /* note, keep deterministic where possible (geometry order independent)
+ * this function assumed all visit faces & edges are tagged */
+
+ BLI_LINKSTACK_DECLARE(vert_queue_prev, BMVert *);
+ BLI_LINKSTACK_DECLARE(vert_queue_next, BMVert *);
+
+ GHash *gh = BLI_ghash_ptr_new(__func__);
+ unsigned int i;
+
+ BMEdge *e_pivot = NULL;
+ /* pick any non-boundary edge (not ideal) */
+ BMEdge *e_pivot_fallback = NULL;
+
+ SUID_Int pass = 0;
+
+ /* total verts in 'gs' we have visited - aka - not v_init_none */
+ unsigned int vert_queue_used = 0;
+
+ BLI_LINKSTACK_INIT(vert_queue_prev);
+ BLI_LINKSTACK_INIT(vert_queue_next);
+
+ /* face-verts */
+ for (i = 0; i < faces_region_len; i++) {
+ BMFace *f = faces_region[i];
+
+ BMLoop *l_iter, *l_first;
+ l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+ do {
+ BMEdge *e = l_iter->e;
+ if (bm_edge_is_region_boundary(e)) {
+ unsigned int j;
+ for (j = 0; j < 2; j++) {
+ if (!BLI_ghash_haskey(gh, (&e->v1)[j])) {
+ SUID_Int v_id = bm_face_region_vert_boundary_id((&e->v1)[j]);
+ BLI_ghash_insert(gh, (&e->v1)[j], (void *)v_id);
+ BLI_LINKSTACK_PUSH(vert_queue_prev, (&e->v1)[j]);
+ vert_queue_used += 1;
+ }
+ }
+ }
+ else {
+ /* use incase (depth == 0), no interior verts */
+ e_pivot_fallback = e;
+ }
+ } while ((l_iter = l_iter->next) != l_first);
+ }
+
+ while (BLI_LINKSTACK_SIZE(vert_queue_prev)) {
+ BMVert *v;
+ while ((v = BLI_LINKSTACK_POP(vert_queue_prev))) {
+ BMIter eiter;
+ BMEdge *e;
+ BLI_assert(BLI_ghash_haskey(gh, v));
+ BLI_assert((SUID_Int)BLI_ghash_lookup(gh, v) > 0);
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
+ BMVert *v_other = BM_edge_other_vert(e, v);
+ if (BM_elem_flag_test(v_other, BM_ELEM_TAG)) {
+ if (!BLI_ghash_haskey(gh, v_other)) {
+ /* add as negative, so we know not to read from them this pass */
+ const SUID_Int v_id_other = -bm_face_region_vert_pass_id(gh, v_other);
+ BLI_ghash_insert(gh, v_other, (void *)v_id_other);
+ BLI_LINKSTACK_PUSH(vert_queue_next, v_other);
+ vert_queue_used += 1;
+ }
+ }
+ }
+ }
+ }
+
+ /* flip all the newly added hashes to positive */
+ {
+ LinkNode *v_link;
+ for (v_link = vert_queue_next; v_link; v_link = v_link->next) {
+ SUID_Int *v_id_p = (SUID_Int *)BLI_ghash_lookup_p(gh, v_link->link);
+ *v_id_p = -(*v_id_p);
+ BLI_assert(*v_id_p > 0);
+ }
+ }
+
+ BLI_LINKSTACK_SWAP(vert_queue_prev, vert_queue_next);
+ pass += 1;
+
+ if (vert_queue_used == verts_region_len) {
+ break;
+ }
+ }
+
+ if (BLI_LINKSTACK_SIZE(vert_queue_prev) >= 2) {
+ /* common case - we managed to find some interior verts */
+ LinkNode *v_link;
+ BMEdge *e_pivot_best = NULL;
+ SUID_Int e_pivot_best_id[2] = {0, 0};
+
+ /* temp untag, so we can quickly know what other verts are in this last pass */
+ for (v_link = vert_queue_prev; v_link; v_link = v_link->next) {
+ BMVert *v = v_link->link;
+ BM_elem_flag_disable(v, BM_ELEM_TAG);
+ }
+
+ /* restore correct tagging */
+ for (v_link = vert_queue_prev; v_link; v_link = v_link->next) {
+ BMIter eiter;
+ BMEdge *e_test;
+
+ BMVert *v = v_link->link;
+ BM_elem_flag_enable(v, BM_ELEM_TAG);
+
+ BM_ITER_ELEM (e_test, &eiter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e_test, BM_ELEM_TAG)) {
+ BMVert *v_other = BM_edge_other_vert(e_test, v);
+ if (BM_elem_flag_test(v_other, BM_ELEM_TAG) == false) {
+ bm_face_region_pivot_edge_use_best(gh, e_test, &e_pivot_best, e_pivot_best_id);
+ }
+ }
+ }
+ }
+
+ e_pivot = e_pivot_best;
+ }
+
+ if ((e_pivot == NULL) && BLI_LINKSTACK_SIZE(vert_queue_prev)) {
+ /* find the best single edge */
+ BMEdge *e_pivot_best = NULL;
+ SUID_Int e_pivot_best_id[2] = {0, 0};
+
+ LinkNode *v_link;
+
+ /* reduce a pass since we're having to step into a previous passes vert,
+ * and will be closer to the boundary */
+ BLI_assert(pass != 0);
+ pass -= 1;
+
+ for (v_link = vert_queue_prev; v_link; v_link = v_link->next) {
+ BMVert *v = v_link->link;
+
+ BMIter eiter;
+ BMEdge *e_test;
+ BM_ITER_ELEM (e_test, &eiter, v, BM_EDGES_OF_VERT) {
+ if (BM_elem_flag_test(e_test, BM_ELEM_TAG)) {
+ BMVert *v_other = BM_edge_other_vert(e_test, v);
+ if (BM_elem_flag_test(v_other, BM_ELEM_TAG)) {
+ bm_face_region_pivot_edge_use_best(gh, e_test, &e_pivot_best, e_pivot_best_id);
+ }
+ }
+ }
+ }
+
+ e_pivot = e_pivot_best;
+ }
+
+ BLI_LINKSTACK_FREE(vert_queue_prev);
+ BLI_LINKSTACK_FREE(vert_queue_next);
+
+ BLI_ghash_free(gh, NULL, NULL);
+
+ if (e_pivot == NULL) {
+#ifdef DEBUG_PRINT
+ printf("%s: using fallback edge!\n", __func__);
+#endif
+ e_pivot = e_pivot_fallback;
+ pass = 0;
+ }
+
+ *r_depth = (unsigned int)pass;
+
+ return e_pivot;
+}
+/** \} */
+
+#endif /* USE_PIVOT_SEARCH */
+
+
+/* -------------------------------------------------------------------- */
+/* Quick UUID pass - identify candidates */
+
+#ifdef USE_PIVOT_FASTMATCH
+
+/** \name Fast Match
+ * \{ */
+
+typedef uintptr_t UUIDFashMatch;
+
+static UUIDFashMatch bm_vert_fasthash_single(BMVert *v)
+{
+ BMIter eiter;
+ BMEdge *e;
+ UUIDFashMatch e_num = 0, f_num = 0, l_num = 0;
+
+#define PRIME_EDGE 7
+#define PRIME_FACE 31
+#define PRIME_LOOP 61
+
+ BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
+ if (!BM_edge_is_wire(e)) {
+ BMLoop *l_iter = e->l;
+ e_num += 1;
+ do {
+ f_num += 1;
+ l_num += (unsigned int)l_iter->f->len;
+ } while ((l_iter = l_iter->radial_next) != e->l);
+ }
+ }
+
+ return ((e_num * PRIME_EDGE) ^
+ (f_num * PRIME_FACE) *
+ (l_num * PRIME_LOOP));
+
+#undef PRIME_EDGE
+#undef PRIME_FACE
+#undef PRIME_LOOP
+}
+
+static UUIDFashMatch *bm_vert_fasthash_create(
+ BMesh *bm, const unsigned int depth)
+{
+ UUIDFashMatch *id_prev;
+ UUIDFashMatch *id_curr;
+ unsigned int pass, i;
+ BMVert *v;
+ BMIter iter;
+
+ id_prev = MEM_mallocN(sizeof(*id_prev) * (unsigned int)bm->totvert, __func__);
+ id_curr = MEM_mallocN(sizeof(*id_curr) * (unsigned int)bm->totvert, __func__);
+
+ BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
+ id_prev[i] = bm_vert_fasthash_single(v);
+ }
+
+ for (pass = 0; pass < depth; pass++) {
+ BMEdge *e;
+
+ memcpy(id_curr, id_prev, sizeof(*id_prev) * (unsigned int)bm->totvert);
+
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_edge_is_wire(e) == false) {
+ const int i1 = BM_elem_index_get(e->v1);
+ const int i2 = BM_elem_index_get(e->v2);
+
+ id_curr[i1] += id_prev[i2];
+ id_curr[i2] += id_prev[i1];
+ }
+ }
+ }
+ MEM_freeN(id_prev);
+
+ return id_curr;
+}
+
+static void bm_vert_fasthash_edge_order(
+ UUIDFashMatch *fm, const BMEdge *e, UUIDFashMatch e_fm[2])
+{
+ e_fm[0] = fm[BM_elem_index_get(e->v1)];
+ e_fm[1] = fm[BM_elem_index_get(e->v2)];
+
+ if (e_fm[0] > e_fm[1]) {
+ SWAP(UUIDFashMatch, e_fm[0], e_fm[1]);
+ }
+}
+
+static bool bm_vert_fasthash_edge_is_match(
+ UUIDFashMatch *fm, const BMEdge *e_a, const BMEdge *e_b)
+{
+ UUIDFashMatch e_a_fm[2];
+ UUIDFashMatch e_b_fm[2];
+
+ bm_vert_fasthash_edge_order(fm, e_a, e_a_fm);
+ bm_vert_fasthash_edge_order(fm, e_b, e_b_fm);
+
+ return ((e_a_fm[0] == e_b_fm[0]) &&
+ (e_a_fm[1] == e_b_fm[1]));
+}
+
+static void bm_vert_fasthash_destroy(
+ UUIDFashMatch *fm)
+{
+ MEM_freeN(fm);
+}
+
+/** \} */
+
+#endif /* USE_PIVOT_FASTMATCH */
+
+
+/**
+ * Take a face-region and return a list of matching face-regions.
+ *
+ * \param faces_region A single, contiguous face-region.
+ * \return A list of matching null-terminated face-region arrays.
+ */
+int BM_mesh_region_match(
+ BMesh *bm,
+ BMFace **faces_region, unsigned int faces_region_len,
+ ListBase *r_face_regions)
+{
+ BMEdge *e_src;
+ BMEdge *e_dst;
+ BMIter iter;
+ unsigned int verts_region_len = 0;
+ unsigned int faces_result_len = 0;
+ /* number of steps from e_src to a boundary vert */
+ unsigned int depth;
+
+
+#ifdef USE_WALKER_REUSE
+ UUIDWalk w_src, w_dst;
+#endif
+
+#ifdef USE_PIVOT_FASTMATCH
+ UUIDFashMatch *fm;
+#endif
+
+#ifdef DEBUG_PRINT
+ int search_num = 0;
+#endif
+
+#ifdef DEBUG_TIME
+ TIMEIT_START(region_match);
+#endif
+
+ /* initialize visited verts */
+ BM_mesh_elem_hflag_disable_all(bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
+ bm_face_array_visit(faces_region, faces_region_len, &verts_region_len, true);
+
+ /* needed for 'ghashutil_bmelem_indexhash' */
+ BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
+
+#ifdef USE_PIVOT_SEARCH
+ e_src = bm_face_region_pivot_edge_find(
+ faces_region, faces_region_len,
+ verts_region_len, &depth);
+
+ /* see which edge is added */
+#if 0
+ BM_select_history_clear(bm);
+ if (e_src) {
+ BM_select_history_store(bm, e_src);
+ }
+#endif
+
+#else
+ /* quick test only! */
+ e_src = BM_mesh_active_edge_get(bm);
+#endif
+
+ if (e_src == NULL) {
+#ifdef DEBUG_PRINT
+ printf("Couldn't find 'e_src'");
+#endif
+ return 0;
+ }
+
+ BLI_listbase_clear(r_face_regions);
+
+#ifdef USE_PIVOT_FASTMATCH
+ if (depth > 0) {
+ fm = bm_vert_fasthash_create(bm, depth);
+ }
+ else {
+ fm = NULL;
+ }
+#endif
+
+#ifdef USE_WALKER_REUSE
+ bm_uuidwalk_init(&w_src, faces_region_len, verts_region_len);
+ bm_uuidwalk_init(&w_dst, faces_region_len, verts_region_len);
+#endif
+
+ BM_ITER_MESH (e_dst, &iter, bm, BM_EDGES_OF_MESH) {
+ BMFace **faces_result;
+ unsigned int faces_result_len_out;
+
+ if (BM_elem_flag_test(e_dst, BM_ELEM_TAG)) {
+ continue;
+ }
+
+#ifdef USE_PIVOT_FASTMATCH
+ if (fm && !bm_vert_fasthash_edge_is_match(fm, e_src, e_dst)) {
+ continue;
+ }
+#endif
+
+#ifdef DEBUG_PRINT
+ search_num += 1;
+#endif
+
+ faces_result = bm_mesh_region_match_pair(
+#ifdef USE_WALKER_REUSE
+ &w_src, &w_dst,
+#endif
+ e_src, e_dst,
+ faces_region_len,
+ verts_region_len,
+ &faces_result_len_out);
+
+ /* tag verts as visited */
+ if (faces_result) {
+ LinkData *link;
+
+ bm_face_array_visit(faces_result, faces_result_len_out, NULL, false);
+
+ link = BLI_genericNodeN(faces_result);
+ BLI_addtail(r_face_regions, link);
+ faces_result_len += 1;
+ }
+ }
+
+#ifdef USE_WALKER_REUSE
+ bm_uuidwalk_free(&w_src);
+ bm_uuidwalk_free(&w_dst);
+#else
+ (void)bm_uuidwalk_clear;
+#endif
+
+#ifdef USE_PIVOT_FASTMATCH
+ if (fm) {
+ bm_vert_fasthash_destroy(fm);
+ }
+#endif
+
+#ifdef DEBUG_PRINT
+ printf("%s: search: %d, found %d\n", __func__, search_num, faces_result_len);
+#endif
+
+#ifdef DEBUG_TIME
+ TIMEIT_END(region_match);
+#endif
+
+ return (int)faces_result_len;
+}
diff --git a/source/blender/bmesh/tools/bmesh_region_match.h b/source/blender/bmesh/tools/bmesh_region_match.h
new file mode 100644
index 00000000000..edf8369b070
--- /dev/null
+++ b/source/blender/bmesh/tools/bmesh_region_match.h
@@ -0,0 +1,33 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BMESH_REGION_MATCH_H__
+#define __BMESH_REGION_MATCH_H__
+
+/** \file blender/bmesh/tools/bmesh_region_match.h
+ * \ingroup bmesh
+ */
+
+int BM_mesh_region_match(
+ BMesh *bm,
+ BMFace **faces_region, unsigned int faces_region_len,
+ ListBase *r_face_regions);
+
+#endif /* __BMESH_REGION_MATCH_H__ */
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index 223ab3eca2a..ffbbb8623ac 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -111,16 +111,28 @@ int collada_export(Scene *sce,
eObjectSet objectSet = (export_settings.selected) ? OB_SET_SELECTED : OB_SET_ALL;
export_settings.export_set = BKE_object_relational_superset(sce, objectSet, (eObRelationTypes)includeFilter);
-
- if (export_settings.sort_by_name)
- bc_bubble_sort_by_Object_name(export_settings.export_set);
+ int export_count = BLI_linklist_length(export_settings.export_set);
+
+ if (export_count==0)
+ {
+ if (export_settings.selected) {
+ fprintf(stderr, "Collada: Found no objects to export.\nPlease ensure that all objects which shall be exported are also visible in the 3D Viewport.\n");
+ }
+ else{
+ fprintf(stderr, "Collada: Your scene seems to be empty. No Objects will be exported.\n");
+ }
+ }
+ else {
+ if (export_settings.sort_by_name)
+ bc_bubble_sort_by_Object_name(export_settings.export_set);
+ }
DocumentExporter exporter(&export_settings);
exporter.exportCurrentScene(sce);
BLI_linklist_free(export_settings.export_set, NULL);
- return 1;
+ return export_count;
}
/* end extern C */
diff --git a/source/blender/compositor/nodes/COM_BlurNode.cpp b/source/blender/compositor/nodes/COM_BlurNode.cpp
index 76e52c14685..f3d0c33d3b3 100644
--- a/source/blender/compositor/nodes/COM_BlurNode.cpp
+++ b/source/blender/compositor/nodes/COM_BlurNode.cpp
@@ -105,6 +105,7 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon
GaussianXBlurOperation *operationx = new GaussianXBlurOperation();
operationx->setData(data);
operationx->setQuality(quality);
+ operationx->checkOpenCL();
converter.addOperation(operationx);
converter.mapInputSocket(getInputSocket(1), operationx->getInputSocket(1));
@@ -112,6 +113,7 @@ void BlurNode::convertToOperations(NodeConverter &converter, const CompositorCon
GaussianYBlurOperation *operationy = new GaussianYBlurOperation();
operationy->setData(data);
operationy->setQuality(quality);
+ operationy->checkOpenCL();
converter.addOperation(operationy);
converter.mapInputSocket(getInputSocket(1), operationy->getInputSocket(1));
diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
index 0aefba3bb7c..0838d281de7 100644
--- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.cpp
@@ -21,6 +21,7 @@
*/
#include "COM_GaussianXBlurOperation.h"
+#include "COM_OpenCLDevice.h"
#include "BLI_math.h"
#include "MEM_guardedalloc.h"
@@ -124,6 +125,32 @@ void GaussianXBlurOperation::executePixel(float output[4], int x, int y, void *d
mul_v4_v4fl(output, color_accum, 1.0f / multiplier_accum);
}
+void GaussianXBlurOperation::executeOpenCL(OpenCLDevice *device,
+ MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer,
+ MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp,
+ list<cl_kernel> *clKernelsToCleanUp)
+{
+ cl_kernel gaussianXBlurOperationKernel = device->COM_clCreateKernel("gaussianXBlurOperationKernel", NULL);
+ cl_int filter_size = this->m_filtersize;
+
+ cl_mem gausstab = clCreateBuffer(device->getContext(),
+ CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
+ sizeof(float) * (this->m_filtersize * 2 + 1),
+ this->m_gausstab,
+ NULL);
+
+ device->COM_clAttachMemoryBufferToKernelParameter(gaussianXBlurOperationKernel, 0, 1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram);
+ device->COM_clAttachOutputMemoryBufferToKernelParameter(gaussianXBlurOperationKernel, 2, clOutputBuffer);
+ device->COM_clAttachMemoryBufferOffsetToKernelParameter(gaussianXBlurOperationKernel, 3, outputMemoryBuffer);
+ clSetKernelArg(gaussianXBlurOperationKernel, 4, sizeof(cl_int), &filter_size);
+ device->COM_clAttachSizeToKernelParameter(gaussianXBlurOperationKernel, 5, this);
+ clSetKernelArg(gaussianXBlurOperationKernel, 6, sizeof(cl_mem), &gausstab);
+
+ device->COM_clEnqueueRange(gaussianXBlurOperationKernel, outputMemoryBuffer, 7, this);
+
+ clReleaseMemObject(gausstab);
+}
+
void GaussianXBlurOperation::deinitExecution()
{
BlurBaseOperation::deinitExecution();
diff --git a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h
index e391320a007..d7ae8b1e3dc 100644
--- a/source/blender/compositor/operations/COM_GaussianXBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianXBlurOperation.h
@@ -40,7 +40,12 @@ public:
* @brief the inner loop of this program
*/
void executePixel(float output[4], int x, int y, void *data);
-
+
+ void executeOpenCL(OpenCLDevice *device,
+ MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer,
+ MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp,
+ list<cl_kernel> *clKernelsToCleanUp);
+
/**
* @brief initialize the execution
*/
@@ -53,5 +58,9 @@ public:
void *initializeTileData(rcti *rect);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
+ void checkOpenCL() {
+ this->setOpenCL(m_data.sizex >= 128);
+ }
};
#endif
diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
index a05a1ab6a23..6172f954087 100644
--- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.cpp
@@ -21,6 +21,7 @@
*/
#include "COM_GaussianYBlurOperation.h"
+#include "COM_OpenCLDevice.h"
#include "BLI_math.h"
#include "MEM_guardedalloc.h"
@@ -126,6 +127,32 @@ void GaussianYBlurOperation::executePixel(float output[4], int x, int y, void *d
mul_v4_v4fl(output, color_accum, 1.0f / multiplier_accum);
}
+void GaussianYBlurOperation::executeOpenCL(OpenCLDevice *device,
+ MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer,
+ MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp,
+ list<cl_kernel> *clKernelsToCleanUp)
+{
+ cl_kernel gaussianYBlurOperationKernel = device->COM_clCreateKernel("gaussianYBlurOperationKernel", NULL);
+ cl_int filter_size = this->m_filtersize;
+
+ cl_mem gausstab = clCreateBuffer(device->getContext(),
+ CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR,
+ sizeof(float) * (this->m_filtersize * 2 + 1),
+ this->m_gausstab,
+ NULL);
+
+ device->COM_clAttachMemoryBufferToKernelParameter(gaussianYBlurOperationKernel, 0, 1, clMemToCleanUp, inputMemoryBuffers, this->m_inputProgram);
+ device->COM_clAttachOutputMemoryBufferToKernelParameter(gaussianYBlurOperationKernel, 2, clOutputBuffer);
+ device->COM_clAttachMemoryBufferOffsetToKernelParameter(gaussianYBlurOperationKernel, 3, outputMemoryBuffer);
+ clSetKernelArg(gaussianYBlurOperationKernel, 4, sizeof(cl_int), &filter_size);
+ device->COM_clAttachSizeToKernelParameter(gaussianYBlurOperationKernel, 5, this);
+ clSetKernelArg(gaussianYBlurOperationKernel, 6, sizeof(cl_mem), &gausstab);
+
+ device->COM_clEnqueueRange(gaussianYBlurOperationKernel, outputMemoryBuffer, 7, this);
+
+ clReleaseMemObject(gausstab);
+}
+
void GaussianYBlurOperation::deinitExecution()
{
BlurBaseOperation::deinitExecution();
diff --git a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h
index 22b6562077d..4b5751c0968 100644
--- a/source/blender/compositor/operations/COM_GaussianYBlurOperation.h
+++ b/source/blender/compositor/operations/COM_GaussianYBlurOperation.h
@@ -40,7 +40,12 @@ public:
* the inner loop of this program
*/
void executePixel(float output[4], int x, int y, void *data);
-
+
+ void executeOpenCL(OpenCLDevice *device,
+ MemoryBuffer *outputMemoryBuffer, cl_mem clOutputBuffer,
+ MemoryBuffer **inputMemoryBuffers, list<cl_mem> *clMemToCleanUp,
+ list<cl_kernel> *clKernelsToCleanUp);
+
/**
* @brief initialize the execution
*/
@@ -53,5 +58,9 @@ public:
void *initializeTileData(rcti *rect);
bool determineDependingAreaOfInterest(rcti *input, ReadBufferOperation *readOperation, rcti *output);
+
+ void checkOpenCL() {
+ this->setOpenCL(m_data.sizex >= 128);
+ }
};
#endif
diff --git a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp
index 9fb9efe4fc7..ddc09ecb483 100644
--- a/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_KeyingBlurOperation.cpp
@@ -49,37 +49,27 @@ void *KeyingBlurOperation::initializeTileData(rcti *rect)
void KeyingBlurOperation::executePixel(float output[4], int x, int y, void *data)
{
MemoryBuffer *inputBuffer = (MemoryBuffer *)data;
+ const int bufferWidth = inputBuffer->getWidth();
float *buffer = inputBuffer->getBuffer();
-
- int bufferWidth = inputBuffer->getWidth();
- int bufferHeight = inputBuffer->getHeight();
-
- int i, count = 0;
-
+ int count = 0;
float average = 0.0f;
if (this->m_axis == 0) {
- for (i = -this->m_size + 1; i < this->m_size; i++) {
- int cx = x + i;
-
- if (cx >= 0 && cx < bufferWidth) {
- int bufferIndex = (y * bufferWidth + cx) * 4;
-
- average += buffer[bufferIndex];
- count++;
- }
+ const int start = max(0, x - this->m_size + 1),
+ end = min(bufferWidth, x + this->m_size);
+ for (int cx = start; cx < end; ++cx) {
+ int bufferIndex = (y * bufferWidth + cx) * 4;
+ average += buffer[bufferIndex];
+ count++;
}
}
else {
- for (i = -this->m_size + 1; i < this->m_size; i++) {
- int cy = y + i;
-
- if (cy >= 0 && cy < bufferHeight) {
- int bufferIndex = (cy * bufferWidth + x) * 4;
-
- average += buffer[bufferIndex];
- count++;
- }
+ const int start = max(0, y - this->m_size + 1),
+ end = min(inputBuffer->getHeight(), y + this->m_size);
+ for (int cy = start; cy < end; ++cy) {
+ int bufferIndex = (cy * bufferWidth + x) * 4;
+ average += buffer[bufferIndex];
+ count++;
}
}
diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
index 17b85847fcf..1633d2a2f1d 100644
--- a/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
+++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.cpp
@@ -188,9 +188,9 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri
BLI_freelistN(&edges);
if (triangulation->triangles_total) {
- rctf *rect;
+ rcti *rect;
rect = triangulation->triangles_AABB =
- (rctf *) MEM_callocN(sizeof(rctf) * triangulation->triangles_total, "voronoi triangulation AABB");
+ (rcti *) MEM_callocN(sizeof(rcti) * triangulation->triangles_total, "voronoi triangulation AABB");
for (i = 0; i < triangulation->triangles_total; i++, rect++) {
int *triangle = triangulation->triangles[i];
@@ -206,11 +206,11 @@ KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTri
minmax_v2v2_v2(min, max, b->co);
minmax_v2v2_v2(min, max, c->co);
- rect->xmin = min[0];
- rect->ymin = min[1];
+ rect->xmin = (int)min[0];
+ rect->ymin = (int)min[1];
- rect->xmax = max[0];
- rect->ymax = max[1];
+ rect->xmax = (int)max[0] + 1;
+ rect->ymax = (int)max[1] + 1;
}
}
@@ -224,7 +224,6 @@ void *KeyingScreenOperation::initializeTileData(rcti *rect)
int triangles_allocated = 0;
int chunk_size = 20;
int i;
- rctf rect_float;
if (this->m_movieClip == NULL)
return NULL;
@@ -242,14 +241,10 @@ void *KeyingScreenOperation::initializeTileData(rcti *rect)
if (!triangulation)
return NULL;
- BLI_rctf_init(&rect_float, rect->xmin, rect->xmax, rect->ymin, rect->ymax);
-
tile_data = (TileData *) MEM_callocN(sizeof(TileData), "keying screen tile data");
for (i = 0; i < triangulation->triangles_total; i++) {
- bool ok = BLI_rctf_isect(&rect_float, &triangulation->triangles_AABB[i], NULL);
-
- if (ok) {
+ if (BLI_rcti_isect(rect, &triangulation->triangles_AABB[i], NULL)) {
tile_data->triangles_total++;
if (tile_data->triangles_total > triangles_allocated) {
@@ -316,7 +311,7 @@ void KeyingScreenOperation::executePixel(float output[4], int x, int y, void *da
for (i = 0; i < tile_data->triangles_total; i++) {
int triangle_idx = tile_data->triangles[i];
- rctf *rect = &triangulation->triangles_AABB[triangle_idx];
+ rcti *rect = &triangulation->triangles_AABB[triangle_idx];
if (IN_RANGE_INCL(x, rect->xmin, rect->xmax) && IN_RANGE_INCL(y, rect->ymin, rect->ymax)) {
int *triangle = triangulation->triangles[triangle_idx];
diff --git a/source/blender/compositor/operations/COM_KeyingScreenOperation.h b/source/blender/compositor/operations/COM_KeyingScreenOperation.h
index 10cf48e57f4..b1a5c0c39c7 100644
--- a/source/blender/compositor/operations/COM_KeyingScreenOperation.h
+++ b/source/blender/compositor/operations/COM_KeyingScreenOperation.h
@@ -47,7 +47,7 @@ protected:
VoronoiTriangulationPoint *triangulated_points;
int (*triangles)[3];
int triangulated_points_total, triangles_total;
- rctf *triangles_AABB;
+ rcti *triangles_AABB;
} TriangulationData;
typedef struct TileData {
diff --git a/source/blender/compositor/operations/COM_MapUVOperation.cpp b/source/blender/compositor/operations/COM_MapUVOperation.cpp
index 87ad1d6afa4..6bf730253e7 100644
--- a/source/blender/compositor/operations/COM_MapUVOperation.cpp
+++ b/source/blender/compositor/operations/COM_MapUVOperation.cpp
@@ -62,7 +62,7 @@ void MapUVOperation::executePixelSampled(float output[4], float x, float y, Pixe
*/
float du = len_v2(deriv[0]);
float dv = len_v2(deriv[1]);
- float factor = 1.0f - threshold * (du + dv);
+ float factor = 1.0f - threshold * (du / m_inputColorProgram->getWidth() + dv / m_inputColorProgram->getHeight());
if (factor < 0.f) alpha = 0.f;
else alpha *= factor;
diff --git a/source/blender/compositor/operations/COM_MixOperation.h b/source/blender/compositor/operations/COM_MixOperation.h
index 479ce161eea..d399edba6e9 100644
--- a/source/blender/compositor/operations/COM_MixOperation.h
+++ b/source/blender/compositor/operations/COM_MixOperation.h
@@ -76,7 +76,7 @@ public:
void setUseValueAlphaMultiply(const bool value) { this->m_valueAlphaMultiply = value; }
- bool useValueAlphaMultiply() { return this->m_valueAlphaMultiply; }
+ inline bool useValueAlphaMultiply() { return this->m_valueAlphaMultiply; }
void setUseClamp(bool value) { this->m_useClamp = value; }
};
diff --git a/source/blender/compositor/operations/COM_OpenCLKernels.cl b/source/blender/compositor/operations/COM_OpenCLKernels.cl
index 00b3825d8b3..1b965eb8659 100644
--- a/source/blender/compositor/operations/COM_OpenCLKernels.cl
+++ b/source/blender/compositor/operations/COM_OpenCLKernels.cl
@@ -250,3 +250,66 @@ __kernel void directionalBlurKernel(__read_only image2d_t inputImage, __write_o
write_imagef(output, coords, col);
}
+
+// KERNEL --- GAUSSIAN BLUR ---
+__kernel void gaussianXBlurOperationKernel(__read_only image2d_t inputImage,
+ int2 offsetInput,
+ __write_only image2d_t output,
+ int2 offsetOutput,
+ int filter_size,
+ int2 dimension,
+ __global float *gausstab,
+ int2 offset)
+{
+ float4 color = {0.0f, 0.0f, 0.0f, 0.0f};
+ int2 coords = {get_global_id(0), get_global_id(1)};
+ coords += offset;
+ const int2 realCoordinate = coords + offsetOutput;
+ int2 inputCoordinate = realCoordinate - offsetInput;
+ float weight = 0.0f;
+
+ int xmin = max(realCoordinate.x - filter_size, 0) - offsetInput.x;
+ int xmax = min(realCoordinate.x + filter_size + 1, dimension.x) - offsetInput.x;
+
+ for (int nx = xmin, i = max(filter_size - realCoordinate.x, 0); nx < xmax; ++nx, ++i) {
+ float w = gausstab[i];
+ inputCoordinate.x = nx;
+ color += read_imagef(inputImage, SAMPLER_NEAREST, inputCoordinate) * w;
+ weight += w;
+ }
+
+ color *= (1.0f / weight);
+
+ write_imagef(output, coords, color);
+}
+
+__kernel void gaussianYBlurOperationKernel(__read_only image2d_t inputImage,
+ int2 offsetInput,
+ __write_only image2d_t output,
+ int2 offsetOutput,
+ int filter_size,
+ int2 dimension,
+ __global float *gausstab,
+ int2 offset)
+{
+ float4 color = {0.0f, 0.0f, 0.0f, 0.0f};
+ int2 coords = {get_global_id(0), get_global_id(1)};
+ coords += offset;
+ const int2 realCoordinate = coords + offsetOutput;
+ int2 inputCoordinate = realCoordinate - offsetInput;
+ float weight = 0.0f;
+
+ int ymin = max(realCoordinate.y - filter_size, 0) - offsetInput.y;
+ int ymax = min(realCoordinate.y + filter_size + 1, dimension.y) - offsetInput.y;
+
+ for (int ny = ymin, i = max(filter_size - realCoordinate.y, 0); ny < ymax; ++ny, ++i) {
+ float w = gausstab[i];
+ inputCoordinate.y = ny;
+ color += read_imagef(inputImage, SAMPLER_NEAREST, inputCoordinate) * w;
+ weight += w;
+ }
+
+ color *= (1.0f / weight);
+
+ write_imagef(output, coords, color);
+}
diff --git a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
index 9a34dccacb1..bcef652a8b5 100644
--- a/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
+++ b/source/blender/compositor/operations/COM_SunBeamsOperation.cpp
@@ -138,22 +138,35 @@ struct BufferLineAccumulator {
int x, y, num;
float v, dv;
float falloff_factor;
+ float border[4];
+
+ if ((int)pt_ofs[0] == 0 && (int)pt_ofs[1] == 0) {
+ copy_v4_v4(output, input->getBuffer() + COM_NUMBER_OF_CHANNELS * ((int)source[0] + input->getWidth() * (int)source[1]));
+ return;
+ }
/* initialise the iteration variables */
float *buffer = init_buffer_iterator(input, source, pt_ofs, dist_min, dist_max, x, y, num, v, dv, falloff_factor);
-
- int tot = 0;
+ zero_v3(border);
+ border[3] = 1.0f;
/* v_local keeps track of when to decrement v (see below) */
float v_local = v - floorf(v);
for (int i = 0; i < num; i++) {
- /* range check, abort when running beyond the image border */
- if (x < rect.xmin || x >= rect.xmax || y < rect.ymin || y >= rect.ymax)
- break;
-
- float f = 1.0f - (float)i * falloff_factor;
- madd_v4_v4fl(output, buffer, buffer[3] * f * f);
+ float weight = 1.0f - (float)i * falloff_factor;
+ weight *= weight;
+
+ /* range check, use last valid color when running beyond the image border */
+ if (x >= rect.xmin && x < rect.xmax && y >= rect.ymin && y < rect.ymax) {
+ madd_v4_v4fl(output, buffer, buffer[3] * weight);
+ /* use as border color in case subsequent pixels are out of bounds */
+ copy_v4_v4(border, buffer);
+ }
+ else {
+ madd_v4_v4fl(output, border, border[3] * weight);
+ }
+
/* TODO implement proper filtering here, see
* http://en.wikipedia.org/wiki/Lanczos_resampling
* http://en.wikipedia.org/wiki/Sinc_function
@@ -161,9 +174,8 @@ struct BufferLineAccumulator {
* using lanczos with x = distance from the line segment,
* normalized to a == 0.5f, could give a good result
*
- * for now just count samples and divide equally at the end ...
+ * for now just divide equally at the end ...
*/
- tot++;
/* decrement u */
x -= fxx;
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 481912f4d1f..296a52e7f20 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -426,74 +426,6 @@ bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int a
/* ************************************************** */
/* UI-Button Interface */
-/**
- * Temporary wrapper for driver operators for buttons to make it easier to create
- * such drivers by rerouting all paths through the active object instead so that
- * they will get picked up by the dependency system.
- *
- * \param C Context pointer - for getting active data
- * \param[in,out] ptr RNA pointer for property's datablock. May be modified as result of path remapping.
- * \param prop RNA definition of property to add for
- * \return MEM_alloc'd string representing the path to the property from the given #PointerRNA
- */
-static char *get_driver_path_hack(bContext *C, PointerRNA *ptr, PropertyRNA *prop)
-{
- ID *id = (ID *)ptr->id.data;
- ScrArea *sa = CTX_wm_area(C);
-
- /* get standard path which may be extended */
- char *basepath = RNA_path_from_ID_to_property(ptr, prop);
- char *path = basepath; /* in case no remapping is needed */
-
-
- /* Remapping will only be performed in the Properties Editor, as only this
- * restricts the subspace of options to the 'active' data (a manageable state)
- */
- // TODO: watch out for pinned context?
- if ((sa) && (sa->spacetype == SPACE_BUTS)) {
- Object *ob = CTX_data_active_object(C);
-
- if (ob && id) {
- /* only id-types which can be remapped to go through objects should be considered */
- switch (GS(id->name)) {
- case ID_TE: /* textures */
- {
- Material *ma = give_current_material(ob, ob->actcol);
- Tex *tex = give_current_material_texture(ma);
-
- /* assumes: texture will only be shown if it is active material's active texture it's ok */
- if ((ID *)tex == id) {
- char name_esc_ma[(sizeof(ma->id.name) - 2) * 2];
- char name_esc_tex[(sizeof(tex->id.name) - 2) * 2];
-
- BLI_strescape(name_esc_ma, ma->id.name + 2, sizeof(name_esc_ma));
- BLI_strescape(name_esc_tex, tex->id.name + 2, sizeof(name_esc_tex));
-
- /* create new path */
- // TODO: use RNA path functions to construct step by step instead?
- // FIXME: maybe this isn't even needed anymore...
- path = BLI_sprintfN("material_slots[\"%s\"].material.texture_slots[\"%s\"].texture.%s",
- name_esc_ma, name_esc_tex, basepath);
-
- /* free old one */
- MEM_freeN(basepath);
- }
- break;
- }
- }
-
- /* fix RNA pointer, as we've now changed the ID root by changing the paths */
- if (basepath != path) {
- /* rebase provided pointer so that it starts from object... */
- RNA_pointer_create(&ob->id, ptr->type, ptr->data, ptr);
- }
- }
- }
-
- /* the path should now have been corrected for use */
- return path;
-}
-
/* Add Driver Button Operator ------------------------ */
static int add_driver_button_exec(bContext *C, wmOperator *op)
@@ -511,7 +443,7 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
index = -1;
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
- char *path = get_driver_path_hack(C, &ptr, prop);
+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
if (path) {
@@ -566,7 +498,7 @@ static int remove_driver_button_exec(bContext *C, wmOperator *op)
index = -1;
if (ptr.id.data && ptr.data && prop) {
- char *path = get_driver_path_hack(C, &ptr, prop);
+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
MEM_freeN(path);
@@ -613,7 +545,7 @@ static int copy_driver_button_exec(bContext *C, wmOperator *op)
uiContextActiveProperty(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
- char *path = get_driver_path_hack(C, &ptr, prop);
+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
if (path) {
/* only copy the driver for the button that this was involved for */
@@ -657,7 +589,7 @@ static int paste_driver_button_exec(bContext *C, wmOperator *op)
uiContextActiveProperty(C, &ptr, &prop, &index);
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
- char *path = get_driver_path_hack(C, &ptr, prop);
+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
if (path) {
/* only copy the driver for the button that this was involved for */
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index 1e4d9bac246..b7ab7fe064d 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -70,7 +70,7 @@ void ED_armature_apply_transform(Object *ob, float mat[4][4])
/* Put the armature into editmode */
ED_armature_to_edit(arm);
- /* Transform the bones*/
+ /* Transform the bones */
ED_armature_transform_bones(arm, mat);
/* Turn the list into an armature */
@@ -100,7 +100,7 @@ void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4])
mul_m4_v3(mat, ebone->head);
mul_m4_v3(mat, ebone->tail);
- /* apply the transfiormed roll back */
+ /* apply the transformed roll back */
mat3_to_vec_roll(tmat, NULL, &ebone->roll);
ebone->rad_head *= scale;
@@ -190,7 +190,7 @@ void ED_armature_origin_set(Scene *scene, Object *ob, float cursor[3], int cente
/* Adjust object location for new centerpoint */
if (centermode && obedit == NULL) {
- mul_mat3_m4_v3(ob->obmat, cent); /* ommit translation part */
+ mul_mat3_m4_v3(ob->obmat, cent); /* omit translation part */
add_v3_v3(ob->loc, cent);
}
}
diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h
index 1d054ffc2e9..6d616384b9a 100644
--- a/source/blender/editors/armature/armature_intern.h
+++ b/source/blender/editors/armature/armature_intern.h
@@ -237,7 +237,7 @@ void armature_select_mirrored(struct bArmature *arm);
void armature_tag_unselect(struct bArmature *arm);
void *get_nearest_bone(struct bContext *C, short findunsel, int x, int y);
-void *get_bone_from_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer, short hits, short findunsel);
+void *get_bone_from_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer, short hits, short findunsel, bool do_nearest);
int bone_looper(struct Object *ob, struct Bone *bone, void *data,
int (*bone_func)(struct Object *, struct Bone *, void *));
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index e4ba8728e55..75fa4a5433f 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -245,7 +245,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
invert_m4_m4(imat, premat);
mul_m4_m4m4(difmat, imat, postmat);
- curbone->roll -= (float)atan2(difmat[2][0], difmat[2][2]);
+ curbone->roll -= atan2f(difmat[2][0], difmat[2][2]);
}
/* Fix Constraints and Other Links to this Bone and Armature */
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index 12d13b05ee1..c6ef76c570c 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -73,7 +73,7 @@ Bone *get_indexed_bone(Object *ob, int index)
/* See if there are any selected bones in this buffer */
/* only bones from base are checked on */
-void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short findunsel)
+void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short findunsel, bool do_nearest)
{
Object *obedit = scene->obedit; // XXX get from context
Bone *bone;
@@ -82,6 +82,7 @@ void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer,
unsigned int hitresult;
short i;
bool takeNext = false;
+ int minsel = 0xffffffff, minunsel = 0xffffffff;
for (i = 0; i < hits; i++) {
hitresult = buffer[3 + (i * 4)];
@@ -102,7 +103,7 @@ void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer,
else
sel = !(bone->flag & BONE_SELECTED);
- data = bone;
+ data = bone;
}
else {
data = NULL;
@@ -123,14 +124,28 @@ void *get_bone_from_selectbuffer(Scene *scene, Base *base, unsigned int *buffer,
if (data) {
if (sel) {
- if (!firstSel) firstSel = data;
- takeNext = 1;
+ if (do_nearest) {
+ if (minsel > buffer[4 * i + 1]) {
+ firstSel = data;
+ minsel = buffer[4 * i + 1];
+ }
+ }
+ else {
+ if (!firstSel) firstSel = data;
+ takeNext = 1;
+ }
}
else {
- if (!firstunSel)
- firstunSel = data;
- if (takeNext)
- return data;
+ if (do_nearest) {
+ if (minunsel > buffer[4 * i + 1]) {
+ firstunSel = data;
+ minunsel = buffer[4 * i + 1];
+ }
+ }
+ else {
+ if (!firstunSel) firstunSel = data;
+ if (takeNext) return data;
+ }
}
}
}
@@ -163,7 +178,7 @@ void *get_nearest_bone(bContext *C, short findunsel, int x, int y)
hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect, true);
if (hits > 0)
- return get_bone_from_selectbuffer(vc.scene, vc.scene->basact, buffer, hits, findunsel);
+ return get_bone_from_selectbuffer(vc.scene, vc.scene->basact, buffer, hits, findunsel, true);
return NULL;
}
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index ba105325b97..d75a23a6322 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -1492,9 +1492,9 @@ static int sk_getSelfIntersections(bContext *C, ListBase *list, SK_Stroke *gestu
return added;
}
-static int cmpIntersections(void *i1, void *i2)
+static int cmpIntersections(const void *i1, const void *i2)
{
- SK_Intersection *isect1 = i1, *isect2 = i2;
+ const SK_Intersection *isect1 = i1, *isect2 = i2;
if (isect1->stroke == isect2->stroke) {
if (isect1->before < isect2->before) {
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 76284ba44de..ba5ef4f3b5d 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -133,14 +133,14 @@ void ED_pose_bone_select(Object *ob, bPoseChannel *pchan, bool select)
/* called from editview.c, for mode-less pose selection */
/* assumes scene obact and basact is still on old situation */
int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits,
- bool extend, bool deselect, bool toggle)
+ bool extend, bool deselect, bool toggle, bool do_nearest)
{
Object *ob = base->object;
Bone *nearBone;
if (!ob || !ob->pose) return 0;
- nearBone = get_bone_from_selectbuffer(scene, base, buffer, hits, 1);
+ nearBone = get_bone_from_selectbuffer(scene, base, buffer, hits, 1, do_nearest);
/* if the bone cannot be affected, don't do anything */
if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c
index 1449453936f..4655deec4c4 100644
--- a/source/blender/editors/curve/editfont.c
+++ b/source/blender/editors/curve/editfont.c
@@ -977,9 +977,12 @@ static int move_cursor(bContext *C, int type, const bool select)
EditFont *ef = cu->editfont;
int cursmove = -1;
+ if ((select) && (ef->selstart == 0)) {
+ ef->selstart = ef->selend = ef->pos + 1;
+ }
+
switch (type) {
case LINE_BEGIN:
- if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
while (ef->pos > 0) {
if (ef->textbuf[ef->pos - 1] == '\n') break;
if (ef->textbufinfo[ef->pos - 1].flag & CU_CHINFO_WRAP) break;
@@ -989,7 +992,6 @@ static int move_cursor(bContext *C, int type, const bool select)
break;
case LINE_END:
- if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
while (ef->pos < ef->len) {
if (ef->textbuf[ef->pos] == 0) break;
if (ef->textbuf[ef->pos] == '\n') break;
@@ -1002,7 +1004,6 @@ static int move_cursor(bContext *C, int type, const bool select)
case PREV_WORD:
{
int pos = ef->pos;
- if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
BLI_str_cursor_step_wchar(ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
ef->pos = pos;
cursmove = FO_CURS;
@@ -1012,7 +1013,6 @@ static int move_cursor(bContext *C, int type, const bool select)
case NEXT_WORD:
{
int pos = ef->pos;
- if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
BLI_str_cursor_step_wchar(ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
ef->pos = pos;
cursmove = FO_CURS;
@@ -1020,35 +1020,29 @@ static int move_cursor(bContext *C, int type, const bool select)
}
case PREV_CHAR:
- if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
ef->pos--;
cursmove = FO_CURS;
break;
case NEXT_CHAR:
- if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
ef->pos++;
cursmove = FO_CURS;
break;
case PREV_LINE:
- if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
cursmove = FO_CURSUP;
break;
case NEXT_LINE:
- if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
cursmove = FO_CURSDOWN;
break;
case PREV_PAGE:
- if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
cursmove = FO_PAGEUP;
break;
case NEXT_PAGE:
- if ((select) && (ef->selstart == 0)) ef->selstart = ef->selend = ef->pos + 1;
cursmove = FO_PAGEDOWN;
break;
}
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 6eac9f14bf6..24c80cbf005 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -123,7 +123,7 @@ void ED_armature_deselect_all(struct Object *obedit, int toggle);
void ED_armature_deselect_all_visible(struct Object *obedit);
int ED_do_pose_selectbuffer(struct Scene *scene, struct Base *base, unsigned int *buffer,
- short hits, bool extend, bool deselect, bool toggle);
+ short hits, bool extend, bool deselect, bool toggle, bool do_nearest);
bool mouse_armature(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
int join_armature_exec(struct bContext *C, struct wmOperator *op);
struct Bone *get_indexed_bone(struct Object *ob, int index);
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index db13c628ade..a9995de068e 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -69,8 +69,6 @@ void ED_image_point_pos__reverse(struct SpaceImage *sima, struct ARegion *ar, co
bool ED_space_image_show_render(struct SpaceImage *sima);
bool ED_space_image_show_paint(struct SpaceImage *sima);
bool ED_space_image_show_uvedit(struct SpaceImage *sima, struct Object *obedit);
-bool ED_space_image_show_texpaint(struct SpaceImage *sima, struct Object *ob);
-bool ED_space_image_show_uvshadow(struct SpaceImage *sima, struct Object *obedit);
bool ED_space_image_paint_curve(const struct bContext *C);
diff --git a/source/blender/editors/include/ED_render.h b/source/blender/editors/include/ED_render.h
index 14595a4c668..ab1dbabe793 100644
--- a/source/blender/editors/include/ED_render.h
+++ b/source/blender/editors/include/ED_render.h
@@ -35,7 +35,6 @@ struct ID;
struct Main;
struct MTex;
struct Render;
-struct RenderInfo;
struct Scene;
struct ScrArea;
struct RegionView3D;
@@ -56,18 +55,6 @@ void ED_render_scene_update(struct Main *bmain, struct Scene *scene, int updated
void ED_viewport_render_kill_jobs(const struct bContext *C, bool free_database);
struct Scene *ED_render_job_get_scene(const struct bContext *C);
-/* render_preview.c */
-
-/* stores rendered preview - is also used for icons */
-typedef struct RenderInfo {
- int pr_rectx;
- int pr_recty;
- short curtile, tottile;
- rcti disprect; /* storage for view3d preview rect */
- unsigned int *rect;
- struct Render *re; /* persistent render */
-} RenderInfo;
-
/* Render the preview
*
* pr_method:
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 1e9756ff771..bc794bf3350 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -295,7 +295,6 @@ typedef enum {
#define UI_GRAD_L_ALT 10
#define UI_PALETTE_COLOR 20
-#define UI_PALETTE_COLOR_ACTIVE 1
/* Drawing
*
diff --git a/source/blender/editors/interface/interface_anim.c b/source/blender/editors/interface/interface_anim.c
index fa0832b6273..48e54270e95 100644
--- a/source/blender/editors/interface/interface_anim.c
+++ b/source/blender/editors/interface/interface_anim.c
@@ -61,7 +61,7 @@ static FCurve *ui_but_get_fcurve(uiBut *but, bAction **action, bool *r_driven)
* but works well enough in typical cases */
int rnaindex = (but->rnaindex == -1) ? 0 : but->rnaindex;
- return rna_get_fcurve(&but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
+ return rna_get_fcurve_context_ui(but->block->evil_C, &but->rnapoin, but->rnaprop, rnaindex, action, r_driven);
}
void ui_but_anim_flag(uiBut *but, float cfra)
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 33bb46ced7f..9138ac92ab9 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -3111,8 +3111,9 @@ static int ui_do_but_KEYEVT(bContext *C, uiBut *but, uiHandleButtonData *data, c
}
}
else if (data->state == BUTTON_STATE_WAIT_KEY_EVENT) {
- if (event->type == MOUSEMOVE)
+ if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
return WM_UI_HANDLER_CONTINUE;
+ }
if (event->val == KM_PRESS) {
if (WM_key_event_string(event->type)[0])
@@ -4255,11 +4256,21 @@ static bool ui_numedit_but_NORMAL(uiBut *but, uiHandleButtonData *data,
return changed;
}
+static void ui_palette_set_active(uiBut *but)
+{
+ if ((int)(but->a1) == UI_PALETTE_COLOR) {
+ Palette *palette = but->rnapoin.id.data;
+ PaletteColor *color = but->rnapoin.data;
+ palette->active_color = BLI_findindex(&palette->colors, color);
+ }
+}
+
static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, const wmEvent *event)
{
if (data->state == BUTTON_STATE_HIGHLIGHT) {
/* first handle click on icondrag type button */
if (event->type == LEFTMOUSE && but->dragpoin && event->val == KM_PRESS) {
+ ui_palette_set_active(but);
if (ui_but_mouse_inside_icon(but, data->region, event)) {
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
@@ -4269,6 +4280,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
}
#ifdef USE_DRAG_TOGGLE
if (event->type == LEFTMOUSE && event->val == KM_PRESS) {
+ ui_palette_set_active(but);
button_activate_state(C, but, BUTTON_STATE_WAIT_DRAG);
data->dragstartx = event->x;
data->dragstarty = event->y;
@@ -4277,6 +4289,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
#endif
/* regular open menu */
if (ELEM(event->type, LEFTMOUSE, PADENTER, RETKEY) && event->val == KM_PRESS) {
+ ui_palette_set_active(but);
button_activate_state(C, but, BUTTON_STATE_MENU_OPEN);
return WM_UI_HANDLER_BREAK;
}
@@ -4306,9 +4319,7 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
else if ((int)(but->a1) == UI_PALETTE_COLOR &&
event->type == DELKEY && event->val == KM_PRESS)
{
- Scene *scene = CTX_data_scene(C);
- Paint *paint = BKE_paint_get_active(scene);
- Palette *palette = BKE_paint_palette(paint);
+ Palette *palette = but->rnapoin.id.data;
PaletteColor *color = but->rnapoin.data;
BKE_palette_color_remove(palette, color);
@@ -4333,13 +4344,6 @@ static int ui_do_but_COLOR(bContext *C, uiBut *but, uiHandleButtonData *data, co
if (event->type == LEFTMOUSE && event->val == KM_RELEASE) {
if ((int)(but->a1) == UI_PALETTE_COLOR) {
- Palette *palette = but->rnapoin.id.data;
- PaletteColor *color = but->rnapoin.data;
- palette->active_color = BLI_findindex(&palette->colors, color);
-
- /* enforce redraw, sometimes state here can already be exit */
- ED_region_tag_redraw(data->region);
-
if (!event->ctrl) {
float color[3];
Scene *scene = CTX_data_scene(C);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index cdc611a60f4..2f66c4a9900 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -225,7 +225,7 @@ struct uiBut {
* (type == NUM), Use to store RNA 'precision' value, for dragging and click-step.
* (type == LABEL), If (a1 == 1.0f) use a2 as a blending factor.
* (type == SEARCH_MENU) Use as number or columns.
- * (type == COLOR) Use as indication of active palette color
+ * (type == COLOR) Use as index in palette (not so good, needs refactor)
*/
float a2;
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 27af550b173..c2bd6d307d1 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1442,7 +1442,7 @@ typedef struct CollItemSearch {
int iconid;
} CollItemSearch;
-static int sort_search_items_list(void *a, void *b)
+static int sort_search_items_list(const void *a, const void *b)
{
CollItemSearch *cis1 = (CollItemSearch *)a;
CollItemSearch *cis2 = (CollItemSearch *)b;
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 364a62bd2a0..b0bea42e3bc 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -2407,8 +2407,7 @@ void uiTemplatePalette(uiLayout *layout, PointerRNA *ptr, const char *propname,
RNA_pointer_create(&palette->id, &RNA_PaletteColor, color, &ptr);
uiDefButR(block, COLOR, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, &ptr, "color", -1, 0.0, 1.0,
- UI_PALETTE_COLOR, (col_id == palette->active_color) ? UI_PALETTE_COLOR_ACTIVE : 0.0, "");
-
+ UI_PALETTE_COLOR, col_id, "");
row_cols++;
col_id++;
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index ff46925edaa..11b9b9c83cc 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -2172,8 +2172,8 @@ static void ui_draw_but_HSVCIRCLE(uiBut *but, uiWidgetColors *wcol, const rcti *
glVertex2f(centx, centy);
for (a = 0; a <= tot; a++, ang += radstep) {
- float si = sin(ang);
- float co = cos(ang);
+ float si = sinf(ang);
+ float co = cosf(ang);
ui_hsvcircle_vals_from_pos(hsv, hsv + 1, rect, centx + co * radius, centy + si * radius);
@@ -2898,11 +2898,18 @@ static void widget_swatch(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
widgetbase_draw(&wtb, wcol);
- if (but->a1 == UI_PALETTE_COLOR && but->a2 == UI_PALETTE_COLOR_ACTIVE) {
+ if (but->a1 == UI_PALETTE_COLOR && ((Palette *)but->rnapoin.id.data)->active_color == (int)but->a2) {
float width = rect->xmax - rect->xmin;
float height = rect->ymax - rect->ymin;
-
- glColor4ubv((unsigned char *)wcol->outline);
+ /* find color luminance and change it slightly */
+ float bw = rgb_to_bw(col);
+
+ if (bw > 0.5)
+ bw -= 0.5;
+ else
+ bw += 0.5;
+
+ glColor4f(bw, bw, bw, 1.0);
glBegin(GL_TRIANGLES);
glVertex2f(rect->xmin + 0.1f * width, rect->ymin + 0.9f * height);
glVertex2f(rect->xmin + 0.1f * width, rect->ymin + 0.5f * height);
@@ -3834,7 +3841,7 @@ void ui_draw_pie_center(uiBlock *block)
int subd = 40;
- float angle = atan2(pie_dir[1], pie_dir[0]);
+ float angle = atan2f(pie_dir[1], pie_dir[0]);
float range = (block->pie_data.flags & UI_PIE_DEGREES_RANGE_LARGE) ? ((float)M_PI / 2.0f) : ((float)M_PI / 4.0f);
glPushMatrix();
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index a4130540b1b..bbf4447dd72 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -96,7 +96,9 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
int use_object_instantiation;
int sort_by_name;
int export_transformation_type;
- int open_sim;
+ int open_sim;
+
+ int export_count;
if (!RNA_struct_property_is_set(op->ptr, "filepath")) {
BKE_report(op->reports, RPT_ERROR, "No filename given");
@@ -148,33 +150,36 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
ED_object_editmode_load(CTX_data_edit_object(C));
-
- if (collada_export(CTX_data_scene(C),
- filepath,
- apply_modifiers,
- export_mesh_type,
- selected,
- include_children,
- include_armatures,
- include_shapekeys,
- deform_bones_only,
-
- active_uv_only,
- include_uv_textures,
- include_material_textures,
- use_texture_copies,
-
- triangulate,
- use_object_instantiation,
- sort_by_name,
- export_transformation_type,
- open_sim))
- {
- return OPERATOR_FINISHED;
+ export_count = collada_export(CTX_data_scene(C),
+ filepath,
+ apply_modifiers,
+ export_mesh_type,
+ selected,
+ include_children,
+ include_armatures,
+ include_shapekeys,
+ deform_bones_only,
+
+ active_uv_only,
+ include_uv_textures,
+ include_material_textures,
+ use_texture_copies,
+
+ triangulate,
+ use_object_instantiation,
+ sort_by_name,
+ export_transformation_type,
+ open_sim);
+
+ if (export_count == 0) {
+ BKE_report(op->reports, RPT_WARNING, "Export file is empty");
+ return OPERATOR_CANCELLED;
}
else {
- BKE_report(op->reports, RPT_WARNING, "Export file not created");
- return OPERATOR_CANCELLED;
+ char buff[100];
+ sprintf(buff, "Exported %d Objects", export_count);
+ BKE_report(op->reports, RPT_INFO, buff);
+ return OPERATOR_FINISHED;
}
}
@@ -350,8 +355,8 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_enum(ot->srna, "export_transformation_type_selection", prop_bc_export_transformation_type, 0,
"Transform", "Transformation type for translation, scale and rotation");
- RNA_def_boolean(ot->srna, "open_sim", 0, "Export for OpenSim",
- "Compatibility mode for OpenSim and compatible online worlds");
+ RNA_def_boolean(ot->srna, "open_sim", 0, "Export to SL/OpenSim",
+ "Compatibility mode for SL, OpenSim and other compatible online worlds");
}
diff --git a/source/blender/editors/mask/mask_edit.c b/source/blender/editors/mask/mask_edit.c
index 1acdff8b824..e2eb32e86d9 100644
--- a/source/blender/editors/mask/mask_edit.c
+++ b/source/blender/editors/mask/mask_edit.c
@@ -550,6 +550,8 @@ void ED_keymap_mask(wmKeyConfig *keyconf)
/* duplicate */
WM_keymap_add_item(keymap, "MASK_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "MASK_OT_copy_splines", CKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "MASK_OT_paste_splines", VKEY, KM_PRESS, KM_CTRL, 0);
/* for image editor only */
WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index 9f8388f1fe0..c3959f90318 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -580,7 +580,10 @@ static bool spline_under_mouse_get(const bContext *C,
}
}
}
- if (closest_spline != NULL) {
+ /* TODO(sergey): Chech whether tesellated spline point is closer
+ * to the mouse than the spline center.
+ */
+ if (closest_dist_squared < 32.0f * 32.0f && closest_spline != NULL) {
*mask_layer_r = closest_layer;
*mask_spline_r = closest_spline;
return true;
@@ -2294,6 +2297,10 @@ static int copy_splines_exec(bContext *C, wmOperator *UNUSED(op))
Mask *mask = CTX_data_edit_mask(C);
MaskLayer *mask_layer = BKE_mask_layer_active(mask);
+ if (mask_layer == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
BKE_mask_clipboard_copy_from_layer(mask_layer);
return OPERATOR_FINISHED;
@@ -2331,6 +2338,10 @@ static int paste_splines_exec(bContext *C, wmOperator *UNUSED(op))
Mask *mask = CTX_data_edit_mask(C);
MaskLayer *mask_layer = BKE_mask_layer_active(mask);
+ if (mask_layer == NULL) {
+ mask_layer = BKE_mask_layer_new(mask, "");
+ }
+
BKE_mask_clipboard_paste_to_layer(CTX_data_main(C), mask_layer);
/* TODO: only update edited splines */
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 76c41adf444..f5a7e82a8a8 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -2157,7 +2157,7 @@ static ListBase *find_hole(KnifeTool_OpData *kcd, ListBase *fedges)
static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, ListBase **mainchain,
ListBase **sidechain)
{
- float **fco, **hco;
+ float (*fco)[2], (*hco)[2];
BMVert **fv;
KnifeVert **hv;
KnifeEdge **he;
@@ -2179,8 +2179,8 @@ static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, L
/* Gather 2d projections of hole and face vertex coordinates.
* Use best-axis projection - not completely accurate, maybe revisit */
axis_dominant_v3(&ax, &ay, f->no);
- hco = BLI_memarena_alloc(kcd->arena, nh * sizeof(float *));
- fco = BLI_memarena_alloc(kcd->arena, nf * sizeof(float *));
+ hco = BLI_memarena_alloc(kcd->arena, nh * sizeof(float[2]));
+ fco = BLI_memarena_alloc(kcd->arena, nf * sizeof(float[2]));
hv = BLI_memarena_alloc(kcd->arena, nh * sizeof(KnifeVert *));
fv = BLI_memarena_alloc(kcd->arena, nf * sizeof(BMVert *));
he = BLI_memarena_alloc(kcd->arena, nh * sizeof(KnifeEdge *));
@@ -2198,7 +2198,6 @@ static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, L
kfv = kfvother;
BLI_assert(kfv == kfe->v1 || kfv == kfe->v2);
}
- hco[i] = BLI_memarena_alloc(kcd->arena, 2 * sizeof(float));
hco[i][0] = kfv->co[ax];
hco[i][1] = kfv->co[ay];
hv[i] = kfv;
@@ -2208,7 +2207,6 @@ static bool find_hole_chains(KnifeTool_OpData *kcd, ListBase *hole, BMFace *f, L
j = 0;
BM_ITER_ELEM (v, &iter, f, BM_VERTS_OF_FACE) {
- fco[j] = BLI_memarena_alloc(kcd->arena, 2 * sizeof(float));
fco[j][0] = v->co[ax];
fco[j][1] = v->co[ay];
fv[j] = v;
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 59fbe739d03..b5508ef8b82 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -75,6 +75,9 @@ typedef struct RingSelOpData {
float (*edges)[2][3];
int totedge;
+ float (*points)[3];
+ int totpoint;
+
ViewContext vc;
Object *ob;
@@ -91,9 +94,8 @@ static void ringsel_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
{
View3D *v3d = CTX_wm_view3d(C);
RingSelOpData *lcd = arg;
- int i;
- if (lcd->totedge > 0) {
+ if ((lcd->totedge > 0) || (lcd->totpoint > 0)) {
if (v3d && v3d->zbuf)
glDisable(GL_DEPTH_TEST);
@@ -101,12 +103,23 @@ static void ringsel_draw(const bContext *C, ARegion *UNUSED(ar), void *arg)
glMultMatrixf(lcd->ob->obmat);
glColor3ub(255, 0, 255);
- glBegin(GL_LINES);
- for (i = 0; i < lcd->totedge; i++) {
- glVertex3fv(lcd->edges[i][0]);
- glVertex3fv(lcd->edges[i][1]);
+ if (lcd->totedge > 0) {
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, lcd->edges);
+ glDrawArrays(GL_LINES, 0, lcd->totedge * 2);
+ glDisableClientState(GL_VERTEX_ARRAY);
+ }
+
+ if (lcd->totpoint > 0) {
+ glPointSize(3.0f);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glVertexPointer(3, GL_FLOAT, 0, lcd->points);
+ glDrawArrays(GL_POINTS, 0, lcd->totpoint);
+ glDisableClientState(GL_VERTEX_ARRAY);
+
+ glPointSize(1.0f);
}
- glEnd();
glPopMatrix();
if (v3d && v3d->zbuf)
@@ -178,52 +191,43 @@ static void edgering_vcos_get(DerivedMesh *dm, BMVert *v[2][2], float r_cos[2][2
}
}
-static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
+static void edgering_vcos_get_pair(DerivedMesh *dm, BMVert *v[2], float r_cos[2][3])
{
- BMEditMesh *em = lcd->em;
- DerivedMesh *dm = EDBM_mesh_deform_dm_get(em);
- BMEdge *eed_start = lcd->eed;
- BMEdge *eed, *eed_last;
- BMVert *v[2][2], *v_last;
- BMWalker walker;
- float (*edges)[2][3] = NULL;
- BLI_array_declare(edges);
- int i, tot = 0;
-
- memset(v, 0, sizeof(v));
-
- if (!eed_start)
- return;
-
- if (lcd->edges) {
- MEM_freeN(lcd->edges);
- lcd->edges = NULL;
- lcd->totedge = 0;
+ if (dm) {
+ int j;
+ for (j = 0; j < 2; j++) {
+ dm->getVertCo(dm, BM_elem_index_get(v[j]), r_cos[j]);
+ }
}
-
- if (!lcd->extend) {
- EDBM_flag_disable_all(lcd->em, BM_ELEM_SELECT);
+ else {
+ int j;
+ for (j = 0; j < 2; j++) {
+ copy_v3_v3(r_cos[j], v[j]->co);
+ }
}
+}
- if (select) {
- BMW_init(&walker, em->bm, BMW_EDGERING,
- BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
- BMW_FLAG_TEST_HIDDEN,
- BMW_NIL_LAY);
-
- for (eed = BMW_begin(&walker, eed_start); eed; eed = BMW_step(&walker)) {
- BM_edge_select_set(em->bm, eed, true);
- }
- BMW_end(&walker);
+static void edgering_preview_free(RingSelOpData *lcd)
+{
+ MEM_SAFE_FREE(lcd->edges);
+ lcd->totedge = 0;
- return;
- }
+ MEM_SAFE_FREE(lcd->points);
+ lcd->totpoint = 0;
+}
- if (dm) {
- BM_mesh_elem_table_ensure(lcd->em->bm, BM_VERT);
- }
+static void edgering_preview_calc_edges(RingSelOpData *lcd, DerivedMesh *dm, const int previewlines)
+{
+ BMesh *bm = lcd->em->bm;
+ BMWalker walker;
+ BMEdge *eed_start = lcd->eed;
+ BMEdge *eed, *eed_last;
+ BMVert *v[2][2] = {{NULL}}, *v_last;
+ float (*edges)[2][3] = NULL;
+ BLI_array_declare(edges);
+ int i, tot = 0;
- BMW_init(&walker, em->bm, BMW_EDGERING,
+ BMW_init(&walker, bm, BMW_EDGERING,
BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
BMW_FLAG_TEST_HIDDEN,
BMW_NIL_LAY);
@@ -261,7 +265,7 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
}
eed_last = eed;
}
-
+
if ((eed_last != eed_start) &&
#ifdef BMW_EDGERING_NGON
BM_edge_share_face_check(eed_last, eed_start)
@@ -274,7 +278,7 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
v[1][1] = v[0][1];
edgering_find_order(eed_last, eed_start, v_last, v);
-
+
BLI_array_grow_items(edges, previewlines);
for (i = 1; i <= previewlines; i++) {
@@ -298,15 +302,83 @@ static void edgering_sel(RingSelOpData *lcd, int previewlines, bool select)
lcd->totedge = tot;
}
+static void edgering_preview_calc_points(RingSelOpData *lcd, DerivedMesh *dm, const int previewlines)
+{
+ float v_cos[2][3];
+ float (*points)[3];
+ int i, tot = 0;
+
+ if (dm) {
+ BM_mesh_elem_table_ensure(lcd->em->bm, BM_VERT);
+ }
+
+ points = MEM_mallocN(sizeof(*lcd->points) * previewlines, __func__);
+
+ edgering_vcos_get_pair(dm, &lcd->eed->v1, v_cos);
+
+ for (i = 1; i <= previewlines; i++) {
+ const float fac = (i / ((float)previewlines + 1));
+ interp_v3_v3v3(points[tot], v_cos[0], v_cos[1], fac);
+ tot++;
+ }
+
+ lcd->points = points;
+ lcd->totpoint = previewlines;
+}
+
+static void edgering_preview_calc(RingSelOpData *lcd, const int previewlines)
+{
+ DerivedMesh *dm;
+
+ BLI_assert(lcd->eed != NULL);
+
+ edgering_preview_free(lcd);
+
+ dm = EDBM_mesh_deform_dm_get(lcd->em);
+ if (dm) {
+ BM_mesh_elem_table_ensure(lcd->em->bm, BM_VERT);
+ }
+
+ if (BM_edge_is_wire(lcd->eed)) {
+ edgering_preview_calc_points(lcd, dm, previewlines);
+ }
+ else {
+ edgering_preview_calc_edges(lcd, dm, previewlines);
+ }
+}
+
+static void edgering_select(RingSelOpData *lcd)
+{
+ BMEditMesh *em = lcd->em;
+ BMEdge *eed_start = lcd->eed;
+ BMWalker walker;
+ BMEdge *eed;
+
+ if (!eed_start)
+ return;
+
+ if (!lcd->extend) {
+ EDBM_flag_disable_all(lcd->em, BM_ELEM_SELECT);
+ }
+
+ BMW_init(&walker, em->bm, BMW_EDGERING,
+ BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP,
+ BMW_FLAG_TEST_HIDDEN,
+ BMW_NIL_LAY);
+
+ for (eed = BMW_begin(&walker, eed_start); eed; eed = BMW_step(&walker)) {
+ BM_edge_select_set(em->bm, eed, true);
+ }
+ BMW_end(&walker);
+}
+
static void ringsel_find_edge(RingSelOpData *lcd, const int previewlines)
{
if (lcd->eed) {
- edgering_sel(lcd, previewlines, false);
+ edgering_preview_calc(lcd, previewlines);
}
- else if (lcd->edges) {
- MEM_freeN(lcd->edges);
- lcd->edges = NULL;
- lcd->totedge = 0;
+ else {
+ edgering_preview_free(lcd);
}
}
@@ -324,26 +396,37 @@ static void ringsel_finish(bContext *C, wmOperator *op)
if (lcd->eed) {
BMEditMesh *em = lcd->em;
+ BMVert *v_eed_orig[2] = {lcd->eed->v1, lcd->eed->v2};
- edgering_sel(lcd, cuts, true);
+ edgering_select(lcd);
if (lcd->do_cut) {
const bool is_macro = (op->opm != NULL);
+ /* a single edge (rare, but better support) */
+ const bool is_single = (BM_edge_is_wire(lcd->eed));
+ const int seltype = is_single ? SUBDIV_SELECT_INNER : SUBDIV_SELECT_LOOPCUT;
+
/* Enable gridfill, so that intersecting loopcut works as one would expect.
* Note though that it will break edgeslide in this specific case.
* See [#31939]. */
BM_mesh_esubdivide(em->bm, BM_ELEM_SELECT,
smoothness, smooth_falloff, true,
0.0f, 0.0f,
- cuts,
- SUBDIV_SELECT_LOOPCUT, SUBD_PATH, 0, true,
+ cuts, seltype, SUBD_PATH, 0, true,
use_only_quads, 0);
/* when used in a macro tessface is already re-recalculated */
EDBM_update_generic(em, (is_macro == false), true);
+ if (is_single) {
+ /* de-select endpoints */
+ BM_vert_select_set(em->bm, v_eed_orig[0], false);
+ BM_vert_select_set(em->bm, v_eed_orig[1], false);
+
+ EDBM_selectmode_flush_ex(lcd->em, SCE_SELECT_VERTEX);
+ }
/* we cant slide multiple edges in vertex select mode */
- if (is_macro && (cuts > 1) && (em->selectmode & SCE_SELECT_VERTEX)) {
+ else if (is_macro && (cuts > 1) && (em->selectmode & SCE_SELECT_VERTEX)) {
EDBM_selectmode_disable(lcd->vc.scene, em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);
}
/* force edge slide to edge select mode in in face select mode */
@@ -378,8 +461,7 @@ static void ringsel_exit(bContext *UNUSED(C), wmOperator *op)
/* deactivate the extra drawing stuff in 3D-View */
ED_region_draw_cb_exit(lcd->ar->type, lcd->draw_handle);
- if (lcd->edges)
- MEM_freeN(lcd->edges);
+ edgering_preview_free(lcd);
ED_region_tag_redraw(lcd->ar);
@@ -594,7 +676,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
ringsel_exit(C, op);
ED_area_headerprint(CTX_wm_area(C), NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_CANCELLED;
case ESCKEY:
if (event->val == KM_RELEASE) {
/* cancel */
diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c
index 3b993332db0..4f149bf2c52 100644
--- a/source/blender/editors/mesh/editmesh_rip.c
+++ b/source/blender/editors/mesh/editmesh_rip.c
@@ -309,8 +309,7 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm)
uid_start = uid;
uid = uid_end + bm->totedge;
- BLI_array_grow_one(eloop_pairs);
- lp = &eloop_pairs[BLI_array_count(eloop_pairs) - 1];
+ lp = BLI_array_append_ret(eloop_pairs);
BM_edge_loop_pair(e_last, &lp->l_a, &lp->l_b); /* no need to check, we know this will be true */
@@ -323,8 +322,7 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm)
}
/* null terminate */
- BLI_array_grow_one(eloop_pairs);
- lp = &eloop_pairs[BLI_array_count(eloop_pairs) - 1];
+ lp = BLI_array_append_ret(eloop_pairs);
lp->l_a = lp->l_b = NULL;
return eloop_pairs;
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 9cdfb43ae15..473da4c9756 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -66,6 +66,8 @@
#include "UI_resources.h"
+#include "bmesh_tools.h"
+
#include "mesh_intern.h" /* own include */
/* use bmesh operator flags for a few operators */
@@ -929,6 +931,96 @@ void MESH_OT_select_similar(wmOperatorType *ot)
}
+/* -------------------------------------------------------------------- */
+/* Select Similar Regions */
+
+static int edbm_select_similar_region_exec(bContext *C, wmOperator *op)
+{
+ Object *obedit = CTX_data_edit_object(C);
+ BMEditMesh *em = BKE_editmesh_from_object(obedit);
+ BMesh *bm = em->bm;
+ bool changed = false;
+
+ /* group vars */
+ int *groups_array;
+ int (*group_index)[2];
+ int group_tot;
+ int i;
+
+ if (bm->totfacesel < 2) {
+ BKE_report(op->reports, RPT_ERROR, "No face regions selected");
+ return OPERATOR_CANCELLED;
+ }
+
+ groups_array = MEM_mallocN(sizeof(*groups_array) * bm->totfacesel, __func__);
+ group_tot = BM_mesh_calc_face_groups(bm, groups_array, &group_index,
+ NULL, NULL,
+ BM_ELEM_SELECT, BM_VERT);
+
+ BM_mesh_elem_table_ensure(bm, BM_FACE);
+
+ for (i = 0; i < group_tot; i++) {
+ ListBase faces_regions;
+ int tot;
+
+ const int fg_sta = group_index[i][0];
+ const int fg_len = group_index[i][1];
+ int j;
+ BMFace **fg = MEM_mallocN(sizeof(*fg) * fg_len, __func__);
+
+
+ for (j = 0; j < fg_len; j++) {
+ fg[j] = BM_face_at_index(bm, groups_array[fg_sta + j]);
+ }
+
+ tot = BM_mesh_region_match(bm, fg, fg_len, &faces_regions);
+
+ MEM_freeN(fg);
+
+ if (tot) {
+ LinkData *link;
+ while ((link = BLI_pophead(&faces_regions))) {
+ BMFace *f, **faces = link->data;
+ unsigned int i = 0;
+ while ((f = faces[i++])) {
+ BM_face_select_set(bm, f, true);
+ }
+ MEM_freeN(faces);
+ MEM_freeN(link);
+
+ changed = true;
+ }
+ }
+ }
+
+ MEM_freeN(groups_array);
+
+ if (changed) {
+ WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
+ }
+ else {
+ BKE_report(op->reports, RPT_WARNING, "No matching face regions found");
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void MESH_OT_select_similar_region(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Select Similar Regions";
+ ot->idname = "MESH_OT_select_similar_region";
+ ot->description = "Select similar face regions to the current selection";
+
+ /* api callbacks */
+ ot->exec = edbm_select_similar_region_exec;
+ ot->poll = ED_operator_editmesh;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+
/* **************** Mode Select *************** */
static int edbm_select_mode_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 3f1023b7fb4..20c7f4eb521 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -1288,7 +1288,8 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
bool mirrx = false, mirry = false, mirrz = false;
int i, repeat;
float clip_dist = 0.0f;
- bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
+ const float fac = RNA_float_get(op->ptr, "factor");
+ const bool use_topology = (me->editflag & ME_EDIT_MIRROR_TOPO) != 0;
const bool xaxis = RNA_boolean_get(op->ptr, "xaxis");
const bool yaxis = RNA_boolean_get(op->ptr, "yaxis");
@@ -1322,12 +1323,12 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op)
repeat = RNA_int_get(op->ptr, "repeat");
if (!repeat)
repeat = 1;
-
+
for (i = 0; i < repeat; i++) {
if (!EDBM_op_callf(em, op,
- "smooth_vert verts=%hv mirror_clip_x=%b mirror_clip_y=%b mirror_clip_z=%b clip_dist=%f "
- "use_axis_x=%b use_axis_y=%b use_axis_z=%b",
- BM_ELEM_SELECT, mirrx, mirry, mirrz, clip_dist, xaxis, yaxis, zaxis))
+ "smooth_vert verts=%hv factor=%f mirror_clip_x=%b mirror_clip_y=%b mirror_clip_z=%b "
+ "clip_dist=%f use_axis_x=%b use_axis_y=%b use_axis_z=%b",
+ BM_ELEM_SELECT, fac, mirrx, mirry, mirrz, clip_dist, xaxis, yaxis, zaxis))
{
return OPERATOR_CANCELLED;
}
@@ -1358,7 +1359,8 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- RNA_def_int(ot->srna, "repeat", 1, 1, 1000, "Number of times to smooth the mesh", "", 1, 100);
+ RNA_def_float(ot->srna, "factor", 0.5f, -10.0f, 10.0f, "Smoothing", "Smoothing factor", 0.0f, 1.0f);
+ RNA_def_int(ot->srna, "repeat", 1, 1, 1000, "Repeat", "Number of times to smooth the mesh", 1, 100);
RNA_def_boolean(ot->srna, "xaxis", 1, "X-Axis", "Smooth along the X axis");
RNA_def_boolean(ot->srna, "yaxis", 1, "Y-Axis", "Smooth along the Y axis");
RNA_def_boolean(ot->srna, "zaxis", 1, "Z-Axis", "Smooth along the Z axis");
diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c
index bf8559add6f..68471bfc2ba 100644
--- a/source/blender/editors/mesh/mesh_data.c
+++ b/source/blender/editors/mesh/mesh_data.c
@@ -47,6 +47,7 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_mesh.h"
+#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_editmesh.h"
@@ -502,6 +503,12 @@ static int mesh_uv_texture_add_exec(bContext *C, wmOperator *UNUSED(op))
if (ED_mesh_uv_texture_add(me, NULL, true) == -1)
return OPERATOR_CANCELLED;
+ if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ Scene *scene = CTX_data_scene(C);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ }
+
return OPERATOR_FINISHED;
}
@@ -622,6 +629,12 @@ static int mesh_uv_texture_remove_exec(bContext *C, wmOperator *UNUSED(op))
if (!ED_mesh_uv_texture_remove_active(me))
return OPERATOR_CANCELLED;
+ if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ Scene *scene = CTX_data_scene(C);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ }
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h
index 76f6cb5ebb8..6ba91097ec4 100644
--- a/source/blender/editors/mesh/mesh_intern.h
+++ b/source/blender/editors/mesh/mesh_intern.h
@@ -137,6 +137,7 @@ void MESH_OT_rip_edge(struct wmOperatorType *ot);
/* *** editmesh_select.c *** */
void MESH_OT_select_similar(struct wmOperatorType *ot);
+void MESH_OT_select_similar_region(struct wmOperatorType *ot);
void MESH_OT_select_mode(struct wmOperatorType *ot);
void MESH_OT_loop_multi_select(struct wmOperatorType *ot);
void MESH_OT_loop_select(struct wmOperatorType *ot);
diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c
index 31653efa735..e7dc5a69d53 100644
--- a/source/blender/editors/mesh/mesh_ops.c
+++ b/source/blender/editors/mesh/mesh_ops.c
@@ -130,6 +130,7 @@ void ED_operatortypes_mesh(void)
WM_operatortype_append(MESH_OT_edge_face_add);
WM_operatortype_append(MESH_OT_shortest_path_pick);
WM_operatortype_append(MESH_OT_select_similar);
+ WM_operatortype_append(MESH_OT_select_similar_region);
WM_operatortype_append(MESH_OT_select_mode);
WM_operatortype_append(MESH_OT_loop_multi_select);
WM_operatortype_append(MESH_OT_mark_seam);
@@ -342,7 +343,7 @@ void ED_keymap_mesh(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MESH_OT_faces_select_linked_flat", FKEY, KM_PRESS, (KM_CTRL | KM_SHIFT | KM_ALT), 0);
- WM_keymap_add_item(keymap, "MESH_OT_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_select_similar", GKEY, KM_PRESS, KM_SHIFT, 0);
/* selection mode */
WM_keymap_add_menu(keymap, "VIEW3D_MT_edit_mesh_select_mode", TABKEY, KM_PRESS, KM_CTRL, 0);
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index d252ae20270..16f4f61f92b 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -999,7 +999,7 @@ static int mirror_facerotation(MFace *a, MFace *b)
return -1;
}
-static int mirror_facecmp(const void *a, const void *b)
+static bool mirror_facecmp(const void *a, const void *b)
{
return (mirror_facerotation((MFace *)a, (MFace *)b) == -1);
}
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index 2402ecb498d..b8957514159 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -682,6 +682,7 @@ static void finish_bake_internal(BakeRender *bkr)
}
BKE_image_release_ibuf(ima, ibuf, NULL);
+ DAG_id_tag_update(&ima->id, 0);
}
}
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 372ca33fa4b..5746f9efd56 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -56,6 +56,7 @@
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_screen.h"
+#include "BKE_depsgraph.h"
#include "RE_engine.h"
#include "RE_pipeline.h"
@@ -260,13 +261,14 @@ static bool write_internal_bake_pixels(
}
/* force OpenGL reload */
-static void reset_images_gpu(BakeImages *bake_images)
+static void refresh_images(BakeImages *bake_images)
{
int i;
for (i = 0; i < bake_images->size; i++) {
Image *ima = bake_images->data[i].image;
if (ima->ok == IMA_OK_LOADED) {
GPU_free_image(ima);
+ DAG_id_tag_update(&ima->id, 0);
}
}
}
@@ -966,7 +968,7 @@ cage_cleanup:
}
if (is_save_internal)
- reset_images_gpu(&bake_images);
+ refresh_images(&bake_images);
cleanup:
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 0d58eaee5fa..abc0516cf2b 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -2411,10 +2411,13 @@ static int drop_named_material_invoke(bContext *C, wmOperator *op, const wmEvent
return OPERATOR_CANCELLED;
assign_material(base->object, ma, 1, BKE_MAT_ASSIGN_USERPREF);
-
+
+ DAG_id_tag_update(&base->object->id, OB_RECALC_OB);
+
+ WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, base->object);
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, CTX_wm_view3d(C));
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_LINKS, ma);
-
+
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index a1b8478a0e1..f19765a5344 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -974,7 +974,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
DAG_id_tag_update(&ob_other->id, OB_RECALC_OB | OB_RECALC_DATA);
copy_v3_v3(centn, cent);
- mul_mat3_m4_v3(ob_other->obmat, centn); /* ommit translation part */
+ mul_mat3_m4_v3(ob_other->obmat, centn); /* omit translation part */
add_v3_v3(ob_other->loc, centn);
BKE_object_where_is_calc(scene, ob_other);
diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c
index 6897861c81c..777bbabb6e8 100644
--- a/source/blender/editors/object/object_vgroup.c
+++ b/source/blender/editors/object/object_vgroup.c
@@ -4324,10 +4324,10 @@ static int vgroup_do_remap(Object *ob, const char *name_array, wmOperator *op)
return OPERATOR_FINISHED;
}
-static int vgroup_sort_name(void *def_a_ptr, void *def_b_ptr)
+static int vgroup_sort_name(const void *def_a_ptr, const void *def_b_ptr)
{
- bDeformGroup *def_a = (bDeformGroup *)def_a_ptr;
- bDeformGroup *def_b = (bDeformGroup *)def_b_ptr;
+ const bDeformGroup *def_a = def_a_ptr;
+ const bDeformGroup *def_b = def_b_ptr;
return BLI_natstrcmp(def_a->name, def_b->name);
}
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index 5401cef8351..76344b77dd3 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -319,7 +319,7 @@ void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra)
if (pset->flag & PE_FADE_TIME && pset->selectmode==SCE_SELECT_POINT) {
LOOP_POINTS {
LOOP_KEYS {
- if (fabs(cfra-*key->time) < pset->fade_frames)
+ if (fabsf(cfra - *key->time) < pset->fade_frames)
key->flag &= ~PEK_HIDE;
else {
key->flag |= PEK_HIDE;
@@ -463,7 +463,7 @@ static bool key_inside_circle(PEData *data, float rad, const float co[3], float
dx= data->mval[0] - screen_co[0];
dy= data->mval[1] - screen_co[1];
- dist= sqrt(dx*dx + dy*dy);
+ dist = sqrtf(dx * dx + dy * dy);
if (dist > rad)
return 0;
@@ -2932,7 +2932,7 @@ static void brush_cut(PEData *data, int pa_index)
d= dv * rad2 - d*d;
if (d > 0.0f) {
- d= sqrt(d);
+ d= sqrtf(d);
cut_time= -(v0*xo0 + v1*xo1 + d);
@@ -3678,7 +3678,7 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
pset->flag &= ~PE_LOCK_FIRST;
if (((pset->brushtype == PE_BRUSH_ADD) ?
- (sqrt(dx * dx + dy * dy) > pset->brush[PE_BRUSH_ADD].step) : (dx != 0 || dy != 0)) || bedit->first)
+ (sqrtf(dx * dx + dy * dy) > pset->brush[PE_BRUSH_ADD].step) : (dx != 0 || dy != 0)) || bedit->first)
{
PEData data= bedit->data;
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 3972ed1c49e..b53891f4880 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -1063,8 +1063,8 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
WM_jobs_start(CTX_wm_manager(C), wm_job);
}
else {
- short dummy_stop, dummy_do_update;
- float dummy_progress;
+ short dummy_stop = 0, dummy_do_update = 0;
+ float dummy_progress = 0.0f;
/* blocking, use with exec() */
fluidbake_startjob((void *)fb, &dummy_stop, &dummy_do_update, &dummy_progress);
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index 01f00a8458a..450a3b19889 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -88,6 +88,7 @@
#include "PIL_time.h"
#include "RE_pipeline.h"
+#include "RE_engine.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -213,6 +214,12 @@ void ED_preview_init_dbase(void)
#endif
}
+static bool check_engine_supports_textures(Scene *scene)
+{
+ RenderEngineType *type = RE_engines_find(scene->r.engine);
+ return type->flag & RE_USE_TEXTURE_PREVIEW;
+}
+
void ED_preview_free_dbase(void)
{
if (G_pr_main)
@@ -299,7 +306,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre
sce->r.cfra = scene->r.cfra;
- if (id_type == ID_TE) {
+ if (id_type == ID_TE && !check_engine_supports_textures(scene)) {
/* Force blender internal for texture icons and nodes render,
* seems commonly used render engines does not support
* such kind of rendering.
@@ -751,12 +758,6 @@ static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int firs
if (sp->pr_rect)
RE_ResultGet32(re, sp->pr_rect);
}
- else {
- /* validate owner */
- //if (ri->rect == NULL)
- // ri->rect= MEM_mallocN(sizeof(int) * ri->pr_rectx*ri->pr_recty, "BIF_previewrender");
- //RE_ResultGet32(re, ri->rect);
- }
/* unassign the pointers, reset vars */
preview_prepare_scene(sp->scene, NULL, GS(id->name), sp);
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 72b4da64c3e..6c996bcbd67 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -58,6 +58,7 @@
#include "BKE_linestyle.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_scene.h"
#include "BKE_texture.h"
@@ -102,8 +103,15 @@ static int material_slot_add_exec(bContext *C, wmOperator *UNUSED(op))
if (!ob)
return OPERATOR_CANCELLED;
-
+
object_add_material_slot(ob);
+
+ if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ Scene *scene = CTX_data_scene(C);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ }
+
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
WM_event_add_notifier(C, NC_MATERIAL | ND_SHADING_PREVIEW, ob);
@@ -138,8 +146,15 @@ static int material_slot_remove_exec(bContext *C, wmOperator *op)
BKE_report(op->reports, RPT_ERROR, "Unable to remove material slot in edit mode");
return OPERATOR_CANCELLED;
}
-
+
object_remove_material_slot(ob);
+
+ if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ Scene *scene = CTX_data_scene(C);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ }
+
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_OB_SHADING, ob);
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 6b58d3d55aa..df7ca9f11b2 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -166,7 +166,6 @@ void ED_render_engine_changed(Main *bmain)
bScreen *sc;
ScrArea *sa;
Scene *scene;
- Material *ma;
for (sc = bmain->screen.first; sc; sc = sc->id.next)
for (sa = sc->areabase.first; sa; sa = sa->next)
@@ -176,13 +175,6 @@ void ED_render_engine_changed(Main *bmain)
for (scene = bmain->scene.first; scene; scene = scene->id.next)
ED_render_id_flush_update(bmain, &scene->id);
-
- /* reset texture painting. Sending one dependency graph signal for any material should
- * refresh any texture slots */
- ma = bmain->mat.first;
- if (ma) {
- DAG_id_tag_update(&ma->id, 0);
- }
}
/***************************** Updates ***********************************
@@ -482,15 +474,22 @@ static void image_changed(Main *bmain, Image *ima)
texture_changed(bmain, tex);
}
-static void scene_changed(Main *bmain, Scene *UNUSED(scene))
+static void scene_changed(Main *bmain, Scene *scene)
{
Object *ob;
Material *ma;
/* glsl */
- for (ob = bmain->object.first; ob; ob = ob->id.next)
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
if (ob->gpulamp.first)
GPU_lamp_free(ob);
+
+ if (ob->mode & OB_MODE_TEXTURE_PAINT) {
+ BKE_texpaint_slots_refresh_object(scene, ob);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ GPU_drawobject_free(ob->derivedFinal);
+ }
+ }
for (ma = bmain->mat.first; ma; ma = ma->id.next)
if (ma->gpumaterial.first)
diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index 7b9ede38b39..e27ef705fad 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -521,14 +521,15 @@ static int project_brush_radius(ViewContext *vc,
}
}
-static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc,
- int x, int y, int *pixel_radius,
- float location[3])
+static bool sculpt_get_brush_geometry(
+ bContext *C, ViewContext *vc,
+ int x, int y, int *pixel_radius,
+ float location[3])
{
Scene *scene = CTX_data_scene(C);
Paint *paint = BKE_paint_get_active_from_context(C);
float mouse[2];
- int hit;
+ bool hit;
mouse[0] = x;
mouse[1] = y;
@@ -1011,7 +1012,8 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
* special mode of drawing will go away */
if ((mode == PAINT_SCULPT) && vc.obact->sculpt) {
float location[3];
- int pixel_radius, hit;
+ int pixel_radius;
+ bool hit;
/* test if brush is over the mesh */
hit = sculpt_get_brush_geometry(C, &vc, x, y, &pixel_radius, location);
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 7c19528a049..f4189b512e5 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -57,6 +57,7 @@
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_brush.h"
#include "BKE_image.h"
#include "BKE_main.h"
@@ -87,6 +88,7 @@
#include "RNA_enum_types.h"
#include "GPU_draw.h"
+#include "GPU_buffers.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -527,8 +529,11 @@ BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
kernel->pixel_len = radius;
}
else {
- radius = br->blur_kernel_radius;
+ if (br->blur_kernel_radius <= 0)
+ br->blur_kernel_radius = 1;
+ radius = br->blur_kernel_radius;
+
side = kernel->side = radius * 2 + 1;
kernel->side_squared = kernel->side * kernel->side;
kernel->wdata = MEM_mallocN(sizeof(float) * kernel->side_squared, "blur kernel data");
@@ -543,11 +548,11 @@ BlurKernel *paint_new_blur_kernel(Brush *br, bool proj)
case KERNEL_GAUSSIAN:
{
- /* at standard deviation of 3.0 kernel is at about zero */
+ /* at 3.0 standard deviations distance, kernel is about zero */
float standard_dev = radius / 3.0f;
/* make the necessary adjustment to the value for use in the normal distribution formula */
- standard_dev = standard_dev * standard_dev * 2;
+ standard_dev = -standard_dev * standard_dev * 2;
for (i = 0; i < side; i++) {
for (j = 0; j < side; j++) {
@@ -749,14 +754,16 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo
copy_v2_v2(pop->prevmouse, mouse);
copy_v2_v2(pop->startmouse, mouse);
- if ((brush->imagepaint_tool == PAINT_TOOL_FILL) && (brush->flag & BRUSH_USE_GRADIENT)) {
- pop->cursor = WM_paint_cursor_activate(CTX_wm_manager(C), image_paint_poll, gradient_draw_line, pop);
- }
-
/* initialize from context */
if (CTX_wm_region_view3d(C)) {
Object *ob = OBACT;
- paint_proj_mesh_data_ensure(C, ob, op);
+ bool uvs, mat, tex, stencil;
+ if (!BKE_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, &stencil)) {
+ BKE_paint_data_warning(op->reports, uvs, mat, tex, stencil);
+ MEM_freeN(pop);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ return NULL;
+ }
pop->mode = PAINT_MODE_3D_PROJECT;
pop->custom_paint = paint_proj_new_stroke(C, ob, mouse, mode);
}
@@ -770,6 +777,10 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo
return NULL;
}
+ if ((brush->imagepaint_tool == PAINT_TOOL_FILL) && (brush->flag & BRUSH_USE_GRADIENT)) {
+ pop->cursor = WM_paint_cursor_activate(CTX_wm_manager(C), image_paint_poll, gradient_draw_line, pop);
+ }
+
settings->imapaint.flag |= IMAGEPAINT_DRAWING;
ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
ED_image_undo_restore, ED_image_undo_free, NULL);
@@ -1378,28 +1389,31 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
* cache in case we are loading a file */
BKE_texpaint_slots_refresh_object(scene, ob);
- paint_proj_mesh_data_ensure(C, ob, op);
-
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+
/* entering paint mode also sets image to editors */
if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
Material *ma = give_current_material(ob, ob->actcol); /* set the current material active paint slot on image editor */
- if (ma->texpaintslot)
+ if (ma && ma->texpaintslot)
ima = ma->texpaintslot[ma->paint_active_slot].ima;
}
else if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
ima = imapaint->canvas;
}
- for (sc = bmain->screen.first; sc; sc = sc->id.next) {
- ScrArea *sa;
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl;
- for (sl = sa->spacedata.first; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)sl;
-
- ED_space_image_set(sima, scene, scene->obedit, ima);
+ if (ima) {
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ if (!sima->pin)
+ ED_space_image_set(sima, scene, scene->obedit, ima);
+ }
}
}
}
@@ -1416,7 +1430,7 @@ static int texture_paint_toggle_exec(bContext *C, wmOperator *op)
toggle_paint_cursor(C, 1);
}
- DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ GPU_drawobject_free(ob->derivedFinal);
WM_event_add_notifier(C, NC_SCENE | ND_MODE, scene);
return OPERATOR_FINISHED;
@@ -1482,12 +1496,17 @@ void PAINT_OT_brush_colors_flip(wmOperatorType *ot)
void ED_imapaint_bucket_fill(struct bContext *C, float color[3], wmOperator *op)
{
+ SpaceImage *sima = CTX_wm_space_image(C);
+ Image *ima = sima->image;
+
ED_undo_paint_push_begin(UNDO_PAINT_IMAGE, op->type->name,
ED_image_undo_restore, ED_image_undo_free, NULL);
paint_2d_bucket_fill(C, color, NULL, NULL, NULL);
ED_undo_paint_push_end(UNDO_PAINT_IMAGE);
+
+ DAG_id_tag_update(&ima->id, 0);
}
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 165888b3c09..5530f947b8c 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -1564,7 +1564,7 @@ void paint_2d_gradient_fill(
sub_v2_v2v2(tangent, image_final, image_init);
line_len = len_squared_v2(tangent);
line_len_sq_inv = 1.0f / line_len;
- line_len = sqrt(line_len);
+ line_len = sqrtf(line_len);
do_float = (ibuf->rect_float != NULL);
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 0fb3e278f40..f9124db7a5e 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -74,6 +74,7 @@
#include "BKE_material.h"
#include "BKE_mesh.h"
#include "BKE_mesh_mapping.h"
+#include "BKE_node.h"
#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -84,6 +85,7 @@
#include "ED_image.h"
#include "ED_mesh.h"
+#include "ED_node.h"
#include "ED_paint.h"
#include "ED_screen.h"
#include "ED_uvedit.h"
@@ -362,7 +364,7 @@ static TexPaintSlot *project_paint_face_paint_slot(const ProjPaintState *ps, int
{
MFace *mf = ps->dm_mface + face_index;
Material *ma = ps->dm->mat[mf->mat_nr];
- return ma->texpaintslot + ma->paint_active_slot;
+ return ma ? ma->texpaintslot + ma->paint_active_slot : NULL;
}
static Image *project_paint_face_paint_image(const ProjPaintState *ps, int face_index)
@@ -373,7 +375,7 @@ static Image *project_paint_face_paint_image(const ProjPaintState *ps, int face_
else {
MFace *mf = ps->dm_mface + face_index;
Material *ma = ps->dm->mat[mf->mat_nr];
- TexPaintSlot *slot = ma->texpaintslot + ma->paint_active_slot;
+ TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_active_slot : NULL;
return slot ? slot->ima : ps->canvas_ima;
}
}
@@ -382,14 +384,14 @@ static TexPaintSlot *project_paint_face_clone_slot(const ProjPaintState *ps, int
{
MFace *mf = ps->dm_mface + face_index;
Material *ma = ps->dm->mat[mf->mat_nr];
- return ma->texpaintslot + ma->paint_clone_slot;
+ return ma ? ma->texpaintslot + ma->paint_clone_slot : NULL;
}
static Image *project_paint_face_clone_image(const ProjPaintState *ps, int face_index)
{
MFace *mf = ps->dm_mface + face_index;
Material *ma = ps->dm->mat[mf->mat_nr];
- TexPaintSlot *slot = ma->texpaintslot + ma->paint_clone_slot;
+ TexPaintSlot *slot = ma ? ma->texpaintslot + ma->paint_clone_slot : NULL;
return slot ? slot->ima : ps->clone_ima;
}
@@ -4077,7 +4079,7 @@ static void *do_projectpaint_thread(void *ph_v)
sub_v2_v2v2(tangent, pos, lastpos);
line_len = len_squared_v2(tangent);
line_len_sq_inv = 1.0f / line_len;
- line_len = sqrt(line_len);
+ line_len = sqrtf(line_len);
switch (brush->gradient_fill_mode) {
case BRUSH_GRADIENT_LINEAR:
@@ -4533,9 +4535,14 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int
settings->imapaint.clone : NULL;
/* setup projection painting data */
- ps->do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? 0 : 1;
- ps->do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? 0 : 1;
- ps->do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? 0 : 1;
+ if (ps->tool != PAINT_TOOL_FILL) {
+ ps->do_backfacecull = (settings->imapaint.flag & IMAGEPAINT_PROJECT_BACKFACE) ? 0 : 1;
+ ps->do_occlude = (settings->imapaint.flag & IMAGEPAINT_PROJECT_XRAY) ? 0 : 1;
+ ps->do_mask_normal = (settings->imapaint.flag & IMAGEPAINT_PROJECT_FLAT) ? 0 : 1;
+ }
+ else {
+ ps->do_backfacecull = ps->do_occlude = ps->do_mask_normal = 0;
+ }
ps->do_new_shading_nodes = BKE_scene_use_new_shading_nodes(scene); /* only cache the value */
if (ps->tool == PAINT_TOOL_CLONE)
@@ -4660,13 +4667,18 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
IDProperty *idgroup;
IDProperty *view_data = NULL;
Object *ob = OBACT;
+ bool uvs, mat, tex;
if (ob == NULL || ob->type != OB_MESH) {
BKE_report(op->reports, RPT_ERROR, "No active mesh object");
return OPERATOR_CANCELLED;
}
- paint_proj_mesh_data_ensure(C, ob, op);
+ if (!BKE_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, NULL)) {
+ BKE_paint_data_warning(op->reports, uvs, mat, tex, true);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ return OPERATOR_CANCELLED;
+ }
project_state_init(C, ob, &ps, BRUSH_STROKE_NORMAL);
@@ -4858,108 +4870,78 @@ void PAINT_OT_image_from_view(wmOperatorType *ot)
* Data generation for projective texturing *
* *******************************************/
+void BKE_paint_data_warning(struct ReportList *reports, bool uvs, bool mat, bool tex, bool stencil)
+{
+ BKE_reportf(reports, RPT_WARNING, "Missing%s%s%s%s detected!",
+ !uvs ? " UVs," : "",
+ !mat ? " Materials," : "",
+ !tex ? " Textures," : "",
+ !stencil ? " Stencil," : ""
+ );
+}
/* Make sure that active object has a material, and assign UVs and image layers if they do not exist */
-void paint_proj_mesh_data_ensure(bContext *C, Object *ob, wmOperator *op)
+bool BKE_paint_proj_mesh_data_check(Scene *scene, Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil)
{
Mesh *me;
int layernum;
- ImagePaintSettings *imapaint = &(CTX_data_tool_settings(C)->imapaint);
- bScreen *sc;
- Scene *scene = CTX_data_scene(C);
- Main *bmain = CTX_data_main(C);
+ ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
Brush *br = BKE_paint_brush(&imapaint->paint);
+ bool hasmat = true;
+ bool hastex = true;
+ bool hasstencil = true;
+ bool hasuvs = true;
+ imapaint->missing_data = 0;
+
BLI_assert(ob->type == OB_MESH);
- /* no material, add one */
- if (ob->totcol == 0) {
- Material *ma = BKE_material_add(CTX_data_main(C), "Material");
- /* no material found, just assign to first slot */
- assign_material(ob, ma, 1, BKE_MAT_ASSIGN_USERPREF);
- proj_paint_add_slot(C, ma, NULL);
- }
- else {
- /* there may be material slots but they may be empty, check */
- int i;
-
- for (i = 1; i < ob->totcol + 1; i++) {
- Material *ma = give_current_material(ob, i);
-
- if (ma) {
- if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
+ if (imapaint->mode == IMAGEPAINT_MODE_MATERIAL) {
+ /* no material, add one */
+ if (ob->totcol == 0) {
+ hasmat = false;
+ hastex = false;
+ }
+ else {
+ /* there may be material slots but they may be empty, check */
+ int i;
+ hasmat = false;
+ hastex = false;
+
+ for (i = 1; i < ob->totcol + 1; i++) {
+ Material *ma = give_current_material(ob, i);
+
+ if (ma) {
+ hasmat = true;
if (!ma->texpaintslot) {
/* refresh here just in case */
BKE_texpaint_slot_refresh_cache(scene, ma);
/* if still no slots, we have to add */
- if (!ma->texpaintslot) {
- proj_paint_add_slot(C, ma, NULL);
-
- if (ma->texpaintslot) {
- for (sc = bmain->screen.first; sc; sc = sc->id.next) {
- ScrArea *sa;
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl;
- for (sl = sa->spacedata.first; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)sl;
-
- ED_space_image_set(sima, scene, scene->obedit, ma->texpaintslot[0].ima);
- }
- }
- }
- }
- }
+ if (ma->texpaintslot) {
+ hastex = true;
+ break;
}
}
+ else {
+ hastex = true;
+ break;
+ }
}
}
- else {
- Material *ma = BKE_material_add(CTX_data_main(C), "Material");
- /* no material found, just assign to first slot */
- assign_material(ob, ma, i, BKE_MAT_ASSIGN_USERPREF);
- proj_paint_add_slot(C, ma, NULL);
- }
}
}
-
- if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) {
+ else if (imapaint->mode == IMAGEPAINT_MODE_IMAGE) {
if (imapaint->canvas == NULL) {
- int width;
- int height;
- Main *bmain = CTX_data_main(C);
- float color[4] = {0.0, 0.0, 0.0, 1.0};
-
- width = 1024;
- height = 1024;
- imapaint->canvas = BKE_image_add_generated(bmain, width, height, "Canvas", 32, false, IMA_GENTYPE_BLANK, color);
-
- GPU_drawobject_free(ob->derivedFinal);
-
- for (sc = bmain->screen.first; sc; sc = sc->id.next) {
- ScrArea *sa;
- for (sa = sc->areabase.first; sa; sa = sa->next) {
- SpaceLink *sl;
- for (sl = sa->spacedata.first; sl; sl = sl->next) {
- if (sl->spacetype == SPACE_IMAGE) {
- SpaceImage *sima = (SpaceImage *)sl;
-
- ED_space_image_set(sima, scene, scene->obedit, imapaint->canvas);
- }
- }
- }
- }
+ hastex = false;
}
}
-
+
me = BKE_mesh_from_object(ob);
layernum = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
if (layernum == 0) {
- BKE_reportf(op->reports, RPT_WARNING, "Object did not have UV map, manual unwrap recommended");
-
- ED_mesh_uv_texture_add(me, "UVMap", true);
+ hasuvs = false;
}
/* Make sure we have a stencil to paint on! */
@@ -4967,16 +4949,29 @@ void paint_proj_mesh_data_ensure(bContext *C, Object *ob, wmOperator *op)
imapaint->flag |= IMAGEPAINT_PROJECT_LAYER_STENCIL;
if (imapaint->stencil == NULL) {
- int width;
- int height;
- Main *bmain = CTX_data_main(C);
- float color[4] = {0.0, 0.0, 0.0, 1.0};
-
- width = 1024;
- height = 1024;
- imapaint->stencil = BKE_image_add_generated(bmain, width, height, "Stencil", 32, false, IMA_GENTYPE_BLANK, color);
+ hasstencil = false;
}
}
+
+ if (!hasuvs) imapaint->missing_data |= IMAGEPAINT_MISSING_UVS;
+ if (!hasmat) imapaint->missing_data |= IMAGEPAINT_MISSING_MATERIAL;
+ if (!hastex) imapaint->missing_data |= IMAGEPAINT_MISSING_TEX;
+ if (!hasstencil) imapaint->missing_data |= IMAGEPAINT_MISSING_STENCIL;
+
+ if (uvs) {
+ *uvs = hasuvs;
+ }
+ if (mat) {
+ *mat = hasmat;
+ }
+ if (tex) {
+ *tex = hastex;
+ }
+ if (stencil) {
+ *stencil = hasstencil;
+ }
+
+ return hasuvs && hasmat && hastex && hasstencil;
}
/* Add layer operator */
@@ -4999,30 +4994,74 @@ static EnumPropertyItem layer_type_items[] = {
{0, NULL, 0, NULL, NULL}
};
-bool proj_paint_add_slot(bContext *C, Material *ma, wmOperator *op)
+static Image *proj_paint_image_create(wmOperator *op, Main *bmain)
+{
+ Image *ima;
+ float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ char imagename[MAX_ID_NAME - 2] = "Material Diffuse Color";
+ int width = 1024;
+ int height = 1024;
+ bool use_float = false;
+ short gen_type = IMA_GENTYPE_BLANK;
+ bool alpha = false;
+
+ if (op) {
+ width = RNA_int_get(op->ptr, "width");
+ height = RNA_int_get(op->ptr, "height");
+ use_float = RNA_boolean_get(op->ptr, "float");
+ gen_type = RNA_enum_get(op->ptr, "generated_type");
+ RNA_float_get_array(op->ptr, "color", color);
+ alpha = RNA_boolean_get(op->ptr, "alpha");
+ RNA_string_get(op->ptr, "name", imagename);
+ }
+ ima = BKE_image_add_generated(bmain, width, height, imagename, alpha ? 32 : 24, use_float,
+ gen_type, color);
+
+ return ima;
+}
+
+static bool proj_paint_add_slot(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
Scene *scene = CTX_data_scene(C);
+ Material *ma;
bool is_bi = BKE_scene_uses_blender_internal(scene);
+ Image *ima = NULL;
if (!ob)
return false;
- if (!ma)
- ma = give_current_material(ob, ob->actcol);
+ ma = give_current_material(ob, ob->actcol);
if (ma) {
+ Main *bmain = CTX_data_main(C);
- if (!is_bi || ma->use_nodes) {
- /* not supported for now */
+ if (!is_bi && BKE_scene_use_new_shading_nodes(scene)) {
+ bNode *imanode;
+ bNodeTree *ntree = ma->nodetree;
+
+ if (!ntree) {
+ ED_node_shader_default(C, &ma->id);
+ ntree = ma->nodetree;
+ }
+
+ ma->use_nodes = true;
+
+ /* try to add an image node */
+ imanode = nodeAddStaticNode(C, ntree, SH_NODE_TEX_IMAGE);
+
+ ima = proj_paint_image_create(op, bmain);
+ imanode->id = &ima->id;
+
+ nodeSetActive(ntree, imanode);
+
+ ntreeUpdateTree(CTX_data_main(C), ntree);
}
else {
MTex *mtex = add_mtex_id(&ma->id, -1);
/* successful creation of mtex layer, now create set */
if (mtex) {
- Main *bmain = CTX_data_main(C);
- Image *ima;
int type = MAP_COL;
int type_id = 0;
@@ -5042,47 +5081,36 @@ bool proj_paint_add_slot(bContext *C, Material *ma, wmOperator *op)
mtex->mapto = type;
if (mtex->tex) {
- float color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
- char imagename[MAX_ID_NAME - 2] = "Material Diffuse Color";
- int width = 1024;
- int height = 1024;
- bool use_float = false;
- short gen_type = IMA_GENTYPE_BLANK;
- bool alpha = false;
-
- if (op) {
- width = RNA_int_get(op->ptr, "width");
- height = RNA_int_get(op->ptr, "height");
- use_float = RNA_boolean_get(op->ptr, "float");
- gen_type = RNA_enum_get(op->ptr, "generated_type");
- RNA_float_get_array(op->ptr, "color", color);
- alpha = RNA_boolean_get(op->ptr, "alpha");
- RNA_string_get(op->ptr, "name", imagename);
- }
-
- ima = mtex->tex->ima = BKE_image_add_generated(bmain, width, height, imagename, alpha ? 32 : 24, use_float,
- gen_type, color);
-
- BKE_texpaint_slot_refresh_cache(scene, ma);
- BKE_image_signal(ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE);
- WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, mtex->tex);
- WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima);
- DAG_id_tag_update(&ma->id, 0);
- ED_area_tag_redraw(CTX_wm_area(C));
+ ima = mtex->tex->ima = proj_paint_image_create(op, bmain);
}
WM_event_add_notifier(C, NC_TEXTURE, CTX_data_scene(C));
- return true;
}
+ WM_event_add_notifier(C, NC_TEXTURE | NA_ADDED, mtex->tex);
+ }
+
+ if (ima) {
+ BKE_texpaint_slot_refresh_cache(scene, ma);
+ BKE_image_signal(ima, NULL, IMA_SIGNAL_USER_NEW_IMAGE);
+ WM_event_add_notifier(C, NC_IMAGE | NA_ADDED, ima);
+ DAG_id_tag_update(&ma->id, 0);
+ ED_area_tag_redraw(CTX_wm_area(C));
+
+ return true;
}
}
-
+
return false;
}
static int texture_paint_add_texture_paint_slot_exec(bContext *C, wmOperator *op)
{
- return proj_paint_add_slot(C, NULL, op);
+ if (proj_paint_add_slot(C, op)) {
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
@@ -5093,6 +5121,12 @@ static int texture_paint_add_texture_paint_slot_invoke(bContext *C, wmOperator *
Material *ma = give_current_material(ob, ob->actcol);
int type = RNA_enum_get(op->ptr, "type");
+ if (!ma) {
+ ma = BKE_material_add(CTX_data_main(C), "Material");
+ /* no material found, just assign to first slot */
+ assign_material(ob, ma, ob->actcol, BKE_MAT_ASSIGN_USERPREF);
+ }
+
type = RNA_enum_from_value(layer_type_items, type);
/* get the name of the texture layer type */
@@ -5180,7 +5214,7 @@ void PAINT_OT_delete_texture_paint_slot(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Delete Texture Paint Slot";
- ot->description = "Add a texture paint slot";
+ ot->description = "Delete selected texture paint slot";
ot->idname = "PAINT_OT_delete_texture_paint_slot";
/* api callbacks */
diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h
index 5e1ac0cf8a8..c3b7ec60e71 100644
--- a/source/blender/editors/sculpt_paint/paint_intern.h
+++ b/source/blender/editors/sculpt_paint/paint_intern.h
@@ -169,8 +169,6 @@ void *paint_proj_new_stroke(struct bContext *C, struct Object *ob, const float m
void paint_proj_stroke(const struct bContext *C, void *ps, const float prevmval_i[2], const float mval_i[2], const bool eraser, float pressure, float distance, float size);
void paint_proj_redraw(const struct bContext *C, void *pps, bool final);
void paint_proj_stroke_done(void *ps);
-void paint_proj_mesh_data_ensure(bContext *C, struct Object *ob, struct wmOperator *op);
-bool proj_paint_add_slot(bContext *C, struct Material *ma, struct wmOperator *op);
void paint_brush_color_get(struct Scene *scene, struct Brush *br, bool color_correction, bool invert, float distance, float pressure, float color[3], struct ColorManagedDisplay *display);
bool paint_use_opacity_masking(struct Brush *brush);
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c
index 8faa4cfaf33..24ef735affe 100644
--- a/source/blender/editors/sculpt_paint/paint_mask.c
+++ b/source/blender/editors/sculpt_paint/paint_mask.c
@@ -319,7 +319,7 @@ static void mask_lasso_px_cb(int x, int y, void *user_data)
static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
{
int mcords_tot;
- int (*mcords)[2] = (int (*)[2])WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
+ const int (*mcords)[2] = WM_gesture_lasso_path_to_array(C, op, &mcords_tot);
if (mcords) {
float clip_planes[4][4], clip_planes_final[4][4];
@@ -349,13 +349,13 @@ static int paint_mask_gesture_lasso_exec(bContext *C, wmOperator *op)
ob = vc.obact;
ED_view3d_ob_project_mat_get(vc.rv3d, ob, data.projviewobjmat);
- BLI_lasso_boundbox(&data.rect, (const int (*)[2])mcords, mcords_tot);
+ BLI_lasso_boundbox(&data.rect, mcords, mcords_tot);
data.width = data.rect.xmax - data.rect.xmin;
- data.px = MEM_callocN(sizeof(*data.px) * data.width * (data.rect.ymax - data.rect.ymin), "lasso_mask_pixel_buffer");
+ data.px = MEM_callocN(sizeof(*data.px) * data.width * (data.rect.ymax - data.rect.ymin), __func__);
fill_poly_v2i_n(
data.rect.xmin, data.rect.ymin, data.rect.xmax, data.rect.ymax,
- (const int (*)[2])mcords, mcords_tot,
+ mcords, mcords_tot,
mask_lasso_px_cb, &data);
ED_view3d_clipping_calc(&bb, clip_planes, &mats, &data.rect);
diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c
index 90161fa87dd..dc6be9caa53 100644
--- a/source/blender/editors/sculpt_paint/paint_ops.c
+++ b/source/blender/editors/sculpt_paint/paint_ops.c
@@ -228,8 +228,9 @@ static int palette_color_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
Paint *paint = BKE_paint_get_active_from_context(C);
Palette *palette = paint->palette;
+ PaletteColor *color = BLI_findlink(&palette->colors, palette->active_color);
- BKE_palette_color_delete(palette);
+ BKE_palette_color_remove(palette, color);
return OPERATOR_FINISHED;
}
@@ -666,7 +667,7 @@ static void stencil_set_target(StencilControlData *scd)
scd->lenorig = len_v2(mdiff);
- scd->init_angle = atan2(mdiff[1], mdiff[0]);
+ scd->init_angle = atan2f(mdiff[1], mdiff[0]);
}
static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *event)
@@ -762,7 +763,7 @@ static void stencil_control_calculate(StencilControlData *scd, const int mval[2]
{
float angle;
sub_v2_v2v2(mdiff, mvalf, scd->pos_target);
- angle = atan2(mdiff[1], mdiff[0]);
+ angle = atan2f(mdiff[1], mdiff[0]);
angle = scd->init_rot + angle - scd->init_angle;
if (angle < 0.0f)
angle += (float)(2 * M_PI);
@@ -915,7 +916,7 @@ static int stencil_fit_image_aspect_exec(bContext *C, wmOperator *op)
stencil_area = br->stencil_dimension[0] * br->stencil_dimension[1];
}
- factor = sqrt(stencil_area / orig_area);
+ factor = sqrtf(stencil_area / orig_area);
if (do_mask) {
br->mask_stencil_dimension[0] = factor * aspx;
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index 8f189b49aa6..101d176b00f 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -283,9 +283,9 @@ static bool paint_brush_update(bContext *C,
const float dx = mouse[0] - stroke->initial_mouse[0];
const float dy = mouse[1] - stroke->initial_mouse[1];
- ups->anchored_size = ups->pixel_radius = sqrt(dx * dx + dy * dy);
+ ups->anchored_size = ups->pixel_radius = sqrtf(dx * dx + dy * dy);
- ups->brush_rotation = atan2(dx, dy) + M_PI;
+ ups->brush_rotation = atan2f(dx, dy) + M_PI;
if (brush->flag & BRUSH_EDGE_TO_EDGE) {
halfway[0] = dx * 0.5f + stroke->initial_mouse[0];
@@ -498,7 +498,7 @@ static float paint_stroke_overlapped_curve(Brush *br, float x, float spacing)
for (i = 0; i < n; i++) {
float xx;
- xx = fabs(x0 + i * h);
+ xx = fabsf(x0 + i * h);
if (xx < 1.0f)
sum += BKE_brush_curve_strength(br, xx, 1);
@@ -758,7 +758,7 @@ bool paint_supports_smooth_stroke(Brush *br, PaintMode mode)
bool paint_supports_texture(PaintMode mode)
{
- /* ommit: PAINT_WEIGHT, PAINT_SCULPT_UV, PAINT_INVALID */
+ /* omit: PAINT_WEIGHT, PAINT_SCULPT_UV, PAINT_INVALID */
return ELEM(mode, PAINT_SCULPT, PAINT_VERTEX, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D);
}
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index f34d0ff3f7b..e03c8a5f106 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -395,7 +395,7 @@ static Image *imapaint_face_image(DerivedMesh *dm, int face_index)
Image *ima;
MFace *mf = dm->getTessFaceArray(dm) + face_index;
Material *ma = dm->mat[mf->mat_nr];
- ima = ma->texpaintslot[ma->paint_active_slot].ima;
+ ima = ma ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
return ima;
}
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 33d0510c08a..766048d54bb 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -192,8 +192,8 @@ typedef struct StrokeCache {
float true_location[3];
float location[3];
- float pen_flip;
- float invert;
+ bool pen_flip;
+ bool invert;
float pressure;
float mouse[2];
float bstrength;
@@ -550,7 +550,7 @@ static bool sculpt_brush_test(SculptBrushTest *test, const float co[3])
if (sculpt_brush_test_clipping(test, co)) {
return 0;
}
- test->dist = sqrt(distsq);
+ test->dist = sqrtf(distsq);
return 1;
}
else {
@@ -809,10 +809,10 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache, float feather, Unifi
return alpha * pressure * feather;
case SCULPT_TOOL_SNAKE_HOOK:
- return feather;
+ return root_alpha * feather;
case SCULPT_TOOL_GRAB:
- return feather;
+ return root_alpha * feather;
case SCULPT_TOOL_ROTATE:
return alpha * pressure * feather;
@@ -2553,7 +2553,7 @@ static void do_flatten_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totno
sub_v3_v3v3(val, intr, vd.co);
if (plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * tex_strength(ss, brush, vd.co, sqrt(test.dist),
+ const float fade = bstrength * tex_strength(ss, brush, vd.co, sqrtf(test.dist),
vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
mul_v3_v3fl(proxy[vd.i], val, fade);
@@ -2626,7 +2626,7 @@ static void do_clay_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
sub_v3_v3v3(val, intr, vd.co);
if (plane_trim(ss->cache, brush, val)) {
- const float fade = bstrength * tex_strength(ss, brush, vd.co, sqrt(test.dist),
+ const float fade = bstrength * tex_strength(ss, brush, vd.co, sqrtf(test.dist),
vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
mul_v3_v3fl(proxy[vd.i], val, fade);
@@ -2792,7 +2792,7 @@ static void do_fill_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
if (plane_trim(ss->cache, brush, val)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co,
- sqrt(test.dist),
+ sqrtf(test.dist),
vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
mul_v3_v3fl(proxy[vd.i], val, fade);
@@ -2856,7 +2856,7 @@ static void do_scrape_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod
if (plane_trim(ss->cache, brush, val)) {
const float fade = bstrength * tex_strength(ss, brush, vd.co,
- sqrt(test.dist),
+ sqrtf(test.dist),
vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f);
mul_v3_v3fl(proxy[vd.i], val, fade);
@@ -2899,7 +2899,7 @@ static void do_gravity(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, fl
BKE_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) {
if (sculpt_brush_test_sq(&test, vd.co)) {
- const float fade = tex_strength(ss, brush, vd.co, sqrt(test.dist), vd.no,
+ const float fade = tex_strength(ss, brush, vd.co, sqrtf(test.dist), vd.no,
vd.fno, vd.mask ? *vd.mask : 0.0f);
mul_v3_v3fl(proxy[vd.i], offset, fade);
@@ -4006,14 +4006,14 @@ static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob)
typedef struct {
SculptSession *ss;
const float *ray_start, *ray_normal;
- int hit;
+ bool hit;
float dist;
int original;
} SculptRaycastData;
typedef struct {
const float *ray_start, *ray_normal;
- int hit;
+ bool hit;
float dist;
float detail;
} SculptDetailRaycastData;
@@ -4145,7 +4145,7 @@ static void sculpt_brush_init_tex(const Scene *scene, Sculpt *sd, SculptSession
sculpt_update_tex(scene, sd, ss);
}
-static int sculpt_brush_stroke_init(bContext *C, wmOperator *op)
+static bool sculpt_brush_stroke_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
Object *ob = CTX_data_active_object(C);
diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 292d6236bab..d90eaafa379 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -273,7 +273,7 @@ static void HC_relaxation_iteration_uv(BMEditMesh *em, UvSculptData *sculptdata,
Temp_UVData *tmp_uvdata;
float diff[2];
int i;
- float radius_root = sqrt(radius);
+ float radius_root = sqrtf(radius);
Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
tmp_uvdata = (Temp_UVData *)MEM_callocN(sculptdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
@@ -316,7 +316,7 @@ static void HC_relaxation_iteration_uv(BMEditMesh *em, UvSculptData *sculptdata,
if ((dist = dot_v2v2(diff, diff)) <= radius) {
UvElement *element;
float strength;
- strength = alpha * BKE_brush_curve_strength(brush, sqrt(dist), radius_root);
+ strength = alpha * BKE_brush_curve_strength(brush, sqrtf(dist), radius_root);
sculptdata->uv[i].uv[0] = (1.0f - strength) * sculptdata->uv[i].uv[0] + strength * (tmp_uvdata[i].p[0] - 0.5f * (tmp_uvdata[i].b[0] + tmp_uvdata[i].sum_b[0] / tmp_uvdata[i].ncounter));
sculptdata->uv[i].uv[1] = (1.0f - strength) * sculptdata->uv[i].uv[1] + strength * (tmp_uvdata[i].p[1] - 0.5f * (tmp_uvdata[i].b[1] + tmp_uvdata[i].sum_b[1] / tmp_uvdata[i].ncounter));
@@ -345,7 +345,7 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em, UvSculptData *scul
Temp_UVData *tmp_uvdata;
float diff[2];
int i;
- float radius_root = sqrt(radius);
+ float radius_root = sqrtf(radius);
Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
tmp_uvdata = (Temp_UVData *)MEM_callocN(sculptdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
@@ -380,7 +380,7 @@ static void laplacian_relaxation_iteration_uv(BMEditMesh *em, UvSculptData *scul
if ((dist = dot_v2v2(diff, diff)) <= radius) {
UvElement *element;
float strength;
- strength = alpha * BKE_brush_curve_strength(brush, sqrt(dist), radius_root);
+ strength = alpha * BKE_brush_curve_strength(brush, sqrtf(dist), radius_root);
sculptdata->uv[i].uv[0] = (1.0f - strength) * sculptdata->uv[i].uv[0] + strength * tmp_uvdata[i].p[0];
sculptdata->uv[i].uv[1] = (1.0f - strength) * sculptdata->uv[i].uv[1] + strength * tmp_uvdata[i].p[1];
@@ -434,7 +434,7 @@ static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, const wmEvent *e
/* We will compare squares to save some computation */
radius = radius * radius;
- radius_root = sqrt(radius);
+ radius_root = sqrtf(radius);
/*
* Pinch Tool
@@ -455,7 +455,7 @@ static void uv_sculpt_stroke_apply(bContext *C, wmOperator *op, const wmEvent *e
if ((dist = dot_v2v2(diff, diff)) <= radius) {
UvElement *element;
float strength;
- strength = alpha * BKE_brush_curve_strength(brush, sqrt(dist), radius_root);
+ strength = alpha * BKE_brush_curve_strength(brush, sqrtf(dist), radius_root);
normalize_v2(diff);
sculptdata->uv[i].uv[0] -= strength * diff[0] * 0.001f;
@@ -563,7 +563,7 @@ static unsigned int uv_edge_hash(const void *key)
BLI_ghashutil_uinthash(edge->uv1));
}
-static int uv_edge_compare(const void *a, const void *b)
+static bool uv_edge_compare(const void *a, const void *b)
{
UvEdge *edge1 = (UvEdge *)a;
UvEdge *edge2 = (UvEdge *)b;
@@ -803,7 +803,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
aspectRatio = width / (float)height;
radius /= (width * zoomx);
radius = radius * radius;
- radius_root = sqrt(radius);
+ radius_root = sqrtf(radius);
/* Allocate selection stack */
data->initial_stroke = MEM_mallocN(sizeof(*data->initial_stroke), "uv_sculpt_initial_stroke");
@@ -829,7 +829,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
diff[1] /= aspectRatio;
if ((dist = dot_v2v2(diff, diff)) <= radius) {
float strength;
- strength = alpha * BKE_brush_curve_strength(brush, sqrt(dist), radius_root);
+ strength = alpha * BKE_brush_curve_strength(brush, sqrtf(dist), radius_root);
data->initial_stroke->initialSelection[counter].uv = i;
data->initial_stroke->initialSelection[counter].strength = strength;
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index a6fbb0c399d..a797a60f74c 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -754,6 +754,10 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
RNA_string_set(kmi->ptr, "value", "INDIVIDUAL_ORIGINS");
+ /* Copy-paste */
+ WM_keymap_add_item(keymap, "CLIP_OT_copy_tracks", CKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "CLIP_OT_paste_tracks", VKEY, KM_PRESS, KM_CTRL, 0);
+
/* ******** Hotkeys avalaible for preview region only ******** */
keymap = WM_keymap_find(keyconf, "Clip Graph Editor", SPACE_CLIP, 0);
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index abbffcd8546..fb6b1a0033c 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -3811,7 +3811,9 @@ static int paste_tracks_exec(bContext *C, wmOperator *UNUSED(op))
MovieClip *clip = ED_space_clip_get_clip(sc);
MovieTracking *tracking = &clip->tracking;
MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
+ ListBase *tracks_base = BKE_tracking_object_get_tracks(tracking, object);
+ BKE_tracking_tracks_deselect_all(tracks_base);
BKE_tracking_clipboard_paste_tracks(tracking, object);
WM_event_add_notifier(C, NC_MOVIECLIP | NA_EDITED, clip);
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index d049a45fd90..1915f45fc87 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -443,7 +443,7 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks)
if (pathString == NULL || !CFStringGetCString(pathString, line, sizeof(line), kCFStringEncodingASCII))
continue;
- fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, FS_INSERT_SORTED);
+ fsmenu_insert_entry(fsmenu, FS_CATEGORY_SYSTEM_BOOKMARKS, line, NULL);
CFRelease(pathString);
CFRelease(cfURL);
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index 7e90008d8d2..ed6e6ba1e1b 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -809,6 +809,10 @@ void uiTemplateImage(uiLayout *layout, bContext *C, PointerRNA *ptr, const char
uiItemR(col, &imaptr, "use_generated_float", 0, NULL, ICON_NONE);
uiItemR(split, &imaptr, "generated_type", UI_ITEM_R_EXPAND, NULL, ICON_NONE);
+
+ if (ima->gen_type == IMA_GENTYPE_BLANK) {
+ uiItemR(layout, &imaptr, "generated_color", 0, NULL, ICON_NONE);
+ }
}
}
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index 24b1c54dd9f..757059ebc29 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -303,13 +303,6 @@ bool ED_space_image_show_paint(SpaceImage *sima)
return (sima->mode == SI_MODE_PAINT);
}
-bool ED_space_image_show_texpaint(SpaceImage *sima, Object *ob)
-{
- return (ob && ob->type == OB_MESH &&
- ob->mode == OB_MODE_TEXTURE_PAINT &&
- !(sima->flag & SI_NO_DRAW_TEXPAINT));
-}
-
bool ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
{
if (sima && (ED_space_image_show_render(sima) || ED_space_image_show_paint(sima)))
@@ -327,24 +320,6 @@ bool ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
return false;
}
-bool ED_space_image_show_uvshadow(SpaceImage *sima, Object *obedit)
-{
- if (ED_space_image_show_render(sima))
- return false;
-
- if (ED_space_image_show_paint(sima))
- if (obedit && obedit->type == OB_MESH) {
- struct BMEditMesh *em = BKE_editmesh_from_object(obedit);
- bool ret;
-
- ret = EDBM_mtexpoly_check(em);
-
- return ret && !(sima->flag & SI_NO_DRAW_TEXPAINT);
- }
-
- return false;
-}
-
/* matches clip function */
bool ED_space_image_check_show_maskedit(Scene *scene, SpaceImage *sima)
{
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index c87e547b6ea..58b56e99119 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -49,17 +49,20 @@
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_depsgraph.h"
+#include "BKE_DerivedMesh.h"
#include "BKE_icons.h"
#include "BKE_image.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_packedFile.h"
+#include "BKE_paint.h"
#include "BKE_report.h"
#include "BKE_screen.h"
#include "BKE_sound.h"
#include "GPU_draw.h"
+#include "GPU_buffers.h"
#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
@@ -1001,10 +1004,10 @@ static void image_sequence_get_frames(PointerRNA *ptr, ListBase *frames, char *p
RNA_END
}
-static int image_cmp_frame(void *a, void *b)
+static int image_cmp_frame(const void *a, const void *b)
{
- ImageFrame *frame_a = (ImageFrame *)a;
- ImageFrame *frame_b = (ImageFrame *)b;
+ const ImageFrame *frame_a = a;
+ const ImageFrame *frame_b = b;
if (frame_a->framenr < frame_b->framenr) return -1;
if (frame_a->framenr > frame_b->framenr) return 1;
@@ -1905,6 +1908,12 @@ void IMAGE_OT_reload(wmOperatorType *ot)
/********************** new image operator *********************/
#define IMA_DEF_NAME N_("Untitled")
+enum {
+ GEN_CONTEXT_NONE = 0,
+ GEN_CONTEXT_PAINT_CANVAS = 1,
+ GEN_CONTEXT_PAINT_STENCIL = 2
+};
+
static int image_new_exec(bContext *C, wmOperator *op)
{
SpaceImage *sima;
@@ -1918,6 +1927,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
char *name = _name;
float color[4];
int width, height, floatbuf, gen_type, alpha;
+ int gen_context;
/* retrieve state */
sima = CTX_wm_space_image(C);
@@ -1937,6 +1947,7 @@ static int image_new_exec(bContext *C, wmOperator *op)
gen_type = RNA_enum_get(op->ptr, "generated_type");
RNA_float_get_array(op->ptr, "color", color);
alpha = RNA_boolean_get(op->ptr, "alpha");
+ gen_context = RNA_enum_get(op->ptr, "gen_context");
if (!alpha)
color[3] = 1.0f;
@@ -1961,6 +1972,40 @@ static int image_new_exec(bContext *C, wmOperator *op)
else if (sima) {
ED_space_image_set(sima, scene, obedit, ima);
}
+ else if (gen_context == GEN_CONTEXT_PAINT_CANVAS) {
+ bScreen *sc;
+ Object *ob = CTX_data_active_object(C);
+
+ GPU_drawobject_free(ob->derivedFinal);
+ if (scene->toolsettings->imapaint.canvas)
+ id_us_min(&scene->toolsettings->imapaint.canvas->id);
+ scene->toolsettings->imapaint.canvas = ima;
+
+ for (sc = bmain->screen.first; sc; sc = sc->id.next) {
+ ScrArea *sa;
+ for (sa = sc->areabase.first; sa; sa = sa->next) {
+ SpaceLink *sl;
+ for (sl = sa->spacedata.first; sl; sl = sl->next) {
+ if (sl->spacetype == SPACE_IMAGE) {
+ SpaceImage *sima = (SpaceImage *)sl;
+
+ if (!sima->pin)
+ ED_space_image_set(sima, scene, scene->obedit, ima);
+ }
+ }
+ }
+ }
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ }
+ else if (gen_context == GEN_CONTEXT_PAINT_STENCIL) {
+ Object *ob = CTX_data_active_object(C);
+ if (scene->toolsettings->imapaint.stencil)
+ id_us_min(&scene->toolsettings->imapaint.stencil->id);
+ scene->toolsettings->imapaint.stencil = ima;
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_TOOLSETTINGS, NULL);
+ }
else {
Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
if (tex && tex->type == TEX_IMAGE) {
@@ -1991,6 +2036,13 @@ void IMAGE_OT_new(wmOperatorType *ot)
{
PropertyRNA *prop;
static float default_color[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+
+ static EnumPropertyItem gen_context_items[] = {
+ {GEN_CONTEXT_NONE, "NONE", 0, "None", ""},
+ {GEN_CONTEXT_PAINT_CANVAS, "PAINT_CANVAS", 0, "Paint Canvas", ""},
+ {GEN_CONTEXT_PAINT_STENCIL, "PAINT_STENCIL", 0, "Paint Stencil", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
/* identifiers */
ot->name = "New Image";
@@ -2017,7 +2069,7 @@ void IMAGE_OT_new(wmOperatorType *ot)
RNA_def_enum(ot->srna, "generated_type", image_generated_type_items, IMA_GENTYPE_BLANK,
"Generated Type", "Fill the image with a grid for UV map testing");
RNA_def_boolean(ot->srna, "float", 0, "32 bit Float", "Create image with 32 bit floating point bit depth");
- prop = RNA_def_boolean(ot->srna, "texstencil", 0, "Stencil", "Set Image as stencil");
+ prop = RNA_def_enum(ot->srna, "gen_context", gen_context_items, 0, "Gen Context", "Generation context");
RNA_def_property_flag(prop, PROP_HIDDEN);
}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index ffe9f13af3f..ab616bf592f 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -540,7 +540,7 @@ static void image_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
break;
}
case NC_WM:
- if(wmn->data == ND_UNDO) {
+ if (wmn->data == ND_UNDO) {
ED_area_tag_redraw(sa);
ED_area_tag_refresh(sa);
}
diff --git a/source/blender/editors/space_node/node_relationships.c b/source/blender/editors/space_node/node_relationships.c
index 97a2383c03f..973ce56857c 100644
--- a/source/blender/editors/space_node/node_relationships.c
+++ b/source/blender/editors/space_node/node_relationships.c
@@ -67,12 +67,12 @@ typedef struct bNodeListItem {
struct bNode *node;
} bNodeListItem;
-static int sort_nodes_locx(void *a, void *b)
+static int sort_nodes_locx(const void *a, const void *b)
{
- bNodeListItem *nli1 = (bNodeListItem *)a;
- bNodeListItem *nli2 = (bNodeListItem *)b;
- bNode *node1 = nli1->node;
- bNode *node2 = nli2->node;
+ const bNodeListItem *nli1 = a;
+ const bNodeListItem *nli2 = b;
+ const bNode *node1 = nli1->node;
+ const bNode *node2 = nli2->node;
if (node1->locx > node2->locx)
return 1;
diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c
index 5a78ea6ebd8..de580f612a0 100644
--- a/source/blender/editors/space_node/node_select.c
+++ b/source/blender/editors/space_node/node_select.c
@@ -248,22 +248,34 @@ static bool node_select_grouped_name(SpaceNode *snode, bNode *node_act, const bo
bNode *node;
bool changed = false;
const unsigned int delims[] = {'.', '-', '_', '\0'};
- size_t index_act, index_curr;
+ size_t pref_len_act, pref_len_curr;
char *sep, *suf_act, *suf_curr;
- index_act = BLI_str_partition_ex_utf8(node_act->name, delims, &sep, &suf_act, from_right);
+ pref_len_act = BLI_str_partition_ex_utf8(node_act->name, delims, &sep, &suf_act, from_right);
- if (index_act > 0) {
- for (node = snode->edittree->nodes.first; node; node = node->next) {
- if ((node->flag & SELECT) == 0) {
- index_curr = BLI_str_partition_ex_utf8(node->name, delims, &sep, &suf_curr, from_right);
- if ((from_right && STREQ(suf_act, suf_curr)) ||
- (!from_right && (index_act == index_curr) && STREQLEN(node_act->name, node->name, index_act)))
- {
- nodeSetSelected(node, true);
- changed = true;
- }
- }
+ /* Note: in case we are searching for suffix, and found none, use whole name as suffix. */
+ if (from_right && !(sep && suf_act)) {
+ pref_len_act = 0;
+ suf_act = node_act->name;
+ }
+
+ for (node = snode->edittree->nodes.first; node; node = node->next) {
+ if (node->flag & SELECT) {
+ continue;
+ }
+ pref_len_curr = BLI_str_partition_ex_utf8(node->name, delims, &sep, &suf_curr, from_right);
+
+ /* Same as with active node name! */
+ if (from_right && !(sep && suf_curr)) {
+ pref_len_curr = 0;
+ suf_curr = node->name;
+ }
+
+ if ((from_right && STREQ(suf_act, suf_curr)) ||
+ (!from_right && (pref_len_act == pref_len_curr) && STREQLEN(node_act->name, node->name, pref_len_act)))
+ {
+ nodeSetSelected(node, true);
+ changed = true;
}
}
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index 875639da113..ccaeae34927 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -511,7 +511,7 @@ static void node_area_listener(bScreen *sc, ScrArea *sa, wmNotifier *wmn)
}
break;
case NC_WM:
- if(wmn->data == ND_UNDO) {
+ if (wmn->data == ND_UNDO) {
ED_area_tag_refresh(sa);
}
break;
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 95802be9ef9..af827d6dc5a 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -373,9 +373,11 @@ static const char *txt_utf8_forward_columns(const char *str, int columns, int *p
static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w, const char *format, int skip)
{
+ const bool use_syntax = (st->showsyntax && format);
FlattenString fs;
int basex, lines;
int i, wrap, end, max, columns, padding; /* column */
+ /* warning, only valid when 'use_syntax' is set */
int a, fstart, fpos; /* utf8 chars */
int mi, ma, mstart, mend; /* mem */
char fmt_prev = 0xff;
@@ -397,8 +399,11 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
/* skip hidden part of line */
if (skip) {
skip--;
- fstart = fpos = end;
- mstart = mend;
+ if (use_syntax) {
+ /* currently fpos only used when formatting */
+ fpos += BLI_strnlen_utf8(str + mstart, mend - mstart);
+ }
+ fstart = fpos; mstart = mend;
mend = txt_utf8_forward_columns(str + mend, max, &padding) - str;
end = (wrap += max - padding);
continue;
@@ -406,7 +411,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
/* Draw the visible portion of text on the overshot line */
for (a = fstart, ma = mstart; ma < mend; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
- if (st->showsyntax && format) {
+ if (use_syntax) {
if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
}
x += text_font_draw_character_utf8(st, x, y, str + ma);
@@ -428,7 +433,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
/* Draw the remaining text */
for (a = fstart, ma = mstart; str[ma] && y > 0; a++, ma += BLI_str_utf8_size_safe(str + ma)) {
- if (st->showsyntax && format) {
+ if (use_syntax) {
if (fmt_prev != format[a]) format_draw_color(fmt_prev = format[a]);
}
@@ -442,6 +447,7 @@ static int text_draw_wrapped(SpaceText *st, const char *str, int x, int y, int w
static void text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int x, int y, const char *format)
{
+ const bool use_syntax = (st->showsyntax && format);
FlattenString fs;
int columns, size, n, w = 0, padding, amount = 0;
const char *in = NULL;
@@ -474,7 +480,7 @@ static void text_draw(SpaceText *st, char *str, int cshift, int maxwidth, int x,
x += st->cwidth * padding;
- if (st->showsyntax && format) {
+ if (use_syntax) {
int a, str_shift = 0;
char fmt_prev = 0xff;
diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c
index 2e3d8d056e8..852edaac7dc 100644
--- a/source/blender/editors/space_text/text_ops.c
+++ b/source/blender/editors/space_text/text_ops.c
@@ -473,7 +473,9 @@ static void txt_write_file(Text *text, ReportList *reports)
for (tmp = text->lines.first; tmp; tmp = tmp->next) {
fputs(tmp->line, fp);
- fputc('\n', fp);
+ if (tmp->next) {
+ fputc('\n', fp);
+ }
}
fclose(fp);
diff --git a/source/blender/editors/space_time/space_time.c b/source/blender/editors/space_time/space_time.c
index 2fd4b0bc21d..88c57d45b79 100644
--- a/source/blender/editors/space_time/space_time.c
+++ b/source/blender/editors/space_time/space_time.c
@@ -405,6 +405,7 @@ static void time_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
case NC_OBJECT:
{
switch (wmn->data) {
+ case ND_BONE_SELECT:
case ND_BONE_ACTIVE:
case ND_POINTCACHE:
case ND_MODIFIER:
diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c
index fb97a6ac9f4..fa9ba23e454 100644
--- a/source/blender/editors/space_view3d/drawmesh.c
+++ b/source/blender/editors/space_view3d/drawmesh.c
@@ -279,10 +279,10 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
if (!ma && BKE_image_has_alpha(texface->tpage))
alphablend = GPU_BLEND_ALPHA;
}
- else if (texpaint && ma) {
+ else if (texpaint) {
if (gtexdraw.texpaint_material)
- ima = ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
- else
+ ima = ma && ma->texpaintslot ? ma->texpaintslot[ma->paint_active_slot].ima : NULL;
+ else
ima = gtexdraw.canvas;
}
else
@@ -315,6 +315,14 @@ static bool set_draw_settings_cached(int clearcache, MTFace *texface, Material *
glActiveTexture(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
+ glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PREVIOUS);
+ glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
+ glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
+ glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
glBindTexture(GL_TEXTURE_2D, ima->bindcode);
glActiveTexture(GL_TEXTURE0);
}
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index e7b6e50ef1c..d155918f7f9 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -302,7 +302,8 @@ bool draw_glsl_material(Scene *scene, Object *ob, View3D *v3d, const char dt)
if (BKE_scene_use_new_shading_nodes(scene))
return false;
- return ((scene->gm.matmode == GAME_MAT_GLSL) || (v3d->drawtype == OB_MATERIAL)) && (dt > OB_SOLID);
+ return ((scene->gm.matmode == GAME_MAT_GLSL && v3d->drawtype == OB_TEXTURE) ||
+ (v3d->drawtype == OB_MATERIAL)) && (dt > OB_SOLID);
}
static bool check_alpha_pass(Base *base)
@@ -5181,7 +5182,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
/* restore & clean up */
if (1) { //ob_dt > OB_WIRE) {
if (part->draw_col == PART_DRAW_COL_MAT)
- glDisable(GL_COLOR_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
glDisable(GL_COLOR_MATERIAL);
}
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index 8b76ec3a56d..0e3621aa91f 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -698,10 +698,6 @@ static void view3d_main_area_free(ARegion *ar)
if (rv3d->localvd) MEM_freeN(rv3d->localvd);
if (rv3d->clipbb) MEM_freeN(rv3d->clipbb);
- if (rv3d->ri) {
- // XXX BIF_view3d_previewrender_free(rv3d);
- }
-
if (rv3d->render_engine)
RE_engine_free(rv3d->render_engine);
@@ -735,7 +731,6 @@ static void *view3d_main_area_duplicate(void *poin)
new->depths = NULL;
new->gpuoffscreen = NULL;
- new->ri = NULL;
new->render_engine = NULL;
new->sms = NULL;
new->smooth_timer = NULL;
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 004b3e1b7d3..61bfb0176ef 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -1091,6 +1091,9 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
/* passepartout, specified in camera edit buttons */
if (ca && (ca->flag & CAM_SHOWPASSEPARTOUT) && ca->passepartalpha > 0.000001f) {
+ const float winx = (ar->winx + 1);
+ const float winy = (ar->winy + 1);
+
if (ca->passepartalpha == 1.0f) {
glColor3f(0, 0, 0);
}
@@ -1100,11 +1103,11 @@ static void drawviewborder(Scene *scene, ARegion *ar, View3D *v3d)
glColor4f(0, 0, 0, ca->passepartalpha);
}
if (x1i > 0.0f)
- glRectf(0.0, (float)ar->winy, x1i, 0.0);
- if (x2i < (float)ar->winx)
- glRectf(x2i, (float)ar->winy, (float)ar->winx, 0.0);
- if (y2i < (float)ar->winy)
- glRectf(x1i, (float)ar->winy, x2i, y2i);
+ glRectf(0.0, winy, x1i, 0.0);
+ if (x2i < winx)
+ glRectf(x2i, winy, winx, 0.0);
+ if (y2i < winy)
+ glRectf(x1i, winy, x2i, y2i);
if (y2i > 0.0f)
glRectf(x1i, y1i, x2i, 0.0);
@@ -1585,6 +1588,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
int fg_flag = do_foreground ? V3D_BGPIC_FOREGROUND : 0;
for (bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
+ bgpic->iuser.scene = scene; /* Needed for render results. */
if ((bgpic->flag & V3D_BGPIC_FOREGROUND) != fg_flag)
continue;
@@ -1598,9 +1602,10 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
float x1, y1, x2, y2;
ImBuf *ibuf = NULL, *freeibuf, *releaseibuf;
+ void *lock;
- Image *ima;
- MovieClip *clip;
+ Image *ima = NULL;
+ MovieClip *clip = NULL;
/* disable individual images */
if ((bgpic->flag & V3D_BGPIC_DISABLED))
@@ -1617,16 +1622,14 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
ibuf = NULL; /* frame is out of range, dont show */
}
else {
- ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, NULL);
+ ibuf = BKE_image_acquire_ibuf(ima, &bgpic->iuser, &lock);
releaseibuf = ibuf;
}
image_aspect[0] = ima->aspx;
- image_aspect[1] = ima->aspx;
+ image_aspect[1] = ima->aspy;
}
else if (bgpic->source == V3D_BGPIC_MOVIE) {
- clip = NULL;
-
/* TODO: skip drawing when out of frame range (as image sequences do above) */
if (bgpic->flag & V3D_BGPIC_CAMERACLIP) {
@@ -1664,7 +1667,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if (freeibuf)
IMB_freeImBuf(freeibuf);
if (releaseibuf)
- BKE_image_release_ibuf(ima, releaseibuf, NULL);
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
continue;
}
@@ -1763,7 +1766,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if (freeibuf)
IMB_freeImBuf(freeibuf);
if (releaseibuf)
- BKE_image_release_ibuf(ima, releaseibuf, NULL);
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
continue;
}
@@ -1830,7 +1833,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d,
if (freeibuf)
IMB_freeImBuf(freeibuf);
if (releaseibuf)
- BKE_image_release_ibuf(ima, releaseibuf, NULL);
+ BKE_image_release_ibuf(ima, releaseibuf, lock);
}
}
}
@@ -1981,8 +1984,10 @@ static void draw_dupli_objects_color(
GLuint displist = 0;
unsigned char color_rgb[3];
const short dflag_dupli = dflag | DRAW_CONSTCOLOR;
- short transflag, use_displist = -1; /* -1 is initialize */
+ short transflag;
+ bool use_displist = false; /* -1 is initialize */
char dt;
+ bool testbb = false;
short dtx;
DupliApplyData *apply_data;
@@ -2037,71 +2042,77 @@ static void draw_dupli_objects_color(
tbase.object->transflag |= OB_NEG_SCALE;
else
tbase.object->transflag &= ~OB_NEG_SCALE;
-
+
/* should move outside the loop but possible color is set in draw_object still */
if ((dflag & DRAW_CONSTCOLOR) == 0) {
glColor3ubv(color_rgb);
}
-
+
/* generate displist, test for new object */
if (dob_prev && dob_prev->ob != dob->ob) {
if (use_displist == true)
glDeleteLists(displist, 1);
-
- use_displist = -1;
+
+ use_displist = false;
+ }
+
+ if ((bb_tmp = BKE_object_boundbox_get(dob->ob))) {
+ bb = *bb_tmp; /* must make a copy */
+ testbb = true;
}
- /* generate displist */
- if (use_displist == -1) {
-
- /* note, since this was added, its checked (dob->type == OB_DUPLIGROUP)
- * however this is very slow, it was probably needed for the NLA
- * offset feature (used in group-duplicate.blend but no longer works in 2.5)
- * so for now it should be ok to - campbell */
-
- if ( /* if this is the last no need to make a displist */
- (dob_next == NULL || dob_next->ob != dob->ob) ||
- /* lamp drawing messes with matrices, could be handled smarter... but this works */
- (dob->ob->type == OB_LAMP) ||
- (dob->type == OB_DUPLIGROUP && dob->animated) ||
- !(bb_tmp = BKE_object_boundbox_get(dob->ob)) ||
- draw_glsl_material(scene, dob->ob, v3d, dt) ||
- check_object_draw_texture(scene, v3d, dt) ||
- (base->object == OBACT && v3d->flag2 & V3D_SOLID_MATCAP))
- {
- // printf("draw_dupli_objects_color: skipping displist for %s\n", dob->ob->id.name + 2);
- use_displist = false;
- }
- else {
- // printf("draw_dupli_objects_color: using displist for %s\n", dob->ob->id.name + 2);
- bb = *bb_tmp; /* must make a copy */
-
- /* disable boundbox check for list creation */
- BKE_object_boundbox_flag(dob->ob, BOUNDBOX_DISABLED, 1);
- /* need this for next part of code */
- unit_m4(dob->ob->obmat); /* obmat gets restored */
-
- displist = glGenLists(1);
- glNewList(displist, GL_COMPILE);
- draw_object(scene, ar, v3d, &tbase, dflag_dupli);
- glEndList();
-
- use_displist = true;
- BKE_object_boundbox_flag(dob->ob, BOUNDBOX_DISABLED, 0);
+ if (!testbb || ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) {
+ /* generate displist */
+ if (use_displist == false) {
+
+ /* note, since this was added, its checked (dob->type == OB_DUPLIGROUP)
+ * however this is very slow, it was probably needed for the NLA
+ * offset feature (used in group-duplicate.blend but no longer works in 2.5)
+ * so for now it should be ok to - campbell */
+
+ if ( /* if this is the last no need to make a displist */
+ (dob_next == NULL || dob_next->ob != dob->ob) ||
+ /* lamp drawing messes with matrices, could be handled smarter... but this works */
+ (dob->ob->type == OB_LAMP) ||
+ (dob->type == OB_DUPLIGROUP && dob->animated) ||
+ !bb_tmp ||
+ draw_glsl_material(scene, dob->ob, v3d, dt) ||
+ check_object_draw_texture(scene, v3d, dt) ||
+ (v3d->flag2 & V3D_SOLID_MATCAP) != 0)
+ {
+ // printf("draw_dupli_objects_color: skipping displist for %s\n", dob->ob->id.name + 2);
+ use_displist = false;
+ }
+ else {
+ // printf("draw_dupli_objects_color: using displist for %s\n", dob->ob->id.name + 2);
+
+ /* disable boundbox check for list creation */
+ BKE_object_boundbox_flag(dob->ob, BOUNDBOX_DISABLED, 1);
+ /* need this for next part of code */
+ unit_m4(dob->ob->obmat); /* obmat gets restored */
+
+ displist = glGenLists(1);
+ glNewList(displist, GL_COMPILE);
+ draw_object(scene, ar, v3d, &tbase, dflag_dupli);
+ glEndList();
+
+ use_displist = true;
+ BKE_object_boundbox_flag(dob->ob, BOUNDBOX_DISABLED, 0);
+ }
}
- }
- if (use_displist) {
- if (ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) {
+
+ if (use_displist) {
+ glPushMatrix();
glMultMatrixf(dob->mat);
glCallList(displist);
- glLoadMatrixf(rv3d->viewmat);
+ glPopMatrix();
+ }
+ else {
+ copy_m4_m4(dob->ob->obmat, dob->mat);
+ draw_object(scene, ar, v3d, &tbase, dflag_dupli);
}
}
- else {
- copy_m4_m4(dob->ob->obmat, dob->mat);
- draw_object(scene, ar, v3d, &tbase, dflag_dupli);
- }
-
+
tbase.object->dt = dt;
tbase.object->dtx = dtx;
tbase.object->transflag = transflag;
@@ -2473,7 +2484,7 @@ static void gpu_update_lamps_shadows(Scene *scene, View3D *v3d)
v3d->drawtype = OB_SOLID;
v3d->lay &= GPU_lamp_shadow_layer(shadow->lamp);
- v3d->flag2 &= ~V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP;
+ v3d->flag2 &= ~(V3D_SOLID_TEX | V3D_SHOW_SOLID_MATCAP);
v3d->flag2 |= V3D_RENDER_OVERRIDE | V3D_RENDER_SHADOW;
GPU_lamp_shadow_buffer_bind(shadow->lamp, viewmat, &winsize, winmat);
@@ -2515,8 +2526,11 @@ CustomDataMask ED_view3d_datamask(Scene *scene, View3D *v3d)
mask |= CD_MASK_ORCO;
}
else {
- if (scene->gm.matmode == GAME_MAT_GLSL || v3d->drawtype == OB_MATERIAL)
+ if ((scene->gm.matmode == GAME_MAT_GLSL && v3d->drawtype == OB_TEXTURE) ||
+ (v3d->drawtype == OB_MATERIAL))
+ {
mask |= CD_MASK_ORCO;
+ }
}
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index db675b09896..f54e7ae06f6 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -1037,8 +1037,8 @@ static void viewrotate_apply(ViewOpsData *vod, int x, int y)
* - dragged. */
phi = si * (float)(M_PI / 2.0);
- q1[0] = cos(phi);
- mul_v3_fl(q1 + 1, sin(phi));
+ q1[0] = cosf(phi);
+ mul_v3_fl(q1 + 1, sinf(phi));
mul_qt_qtqt(vod->viewquat, q1, vod->oldquat);
viewrotate_apply_dyn_ofs(vod, vod->viewquat);
@@ -1448,7 +1448,7 @@ static void view3d_ndof_orbit(const struct wmNDOFMotionData *ndof, ScrArea *sa,
/* Perform the up/down rotation */
angle = ndof->dt * rot[0];
quat[0] = cosf(angle);
- mul_v3_v3fl(quat + 1, xvec, sin(angle));
+ mul_v3_v3fl(quat + 1, xvec, sinf(angle));
mul_qt_qtqt(rv3d->viewquat, rv3d->viewquat, quat);
/* Perform the orbital rotation */
@@ -3423,7 +3423,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
/* find the closest Z pixel */
depth_close = view3d_depth_near(&depth_temp);
- MEM_freeN(depth_temp.depths);
+ MEM_SAFE_FREE(depth_temp.depths);
}
cent[0] = (((double)rect.xmin) + ((double)rect.xmax)) / 2;
@@ -4640,7 +4640,7 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg
view3d_update_depths_rect(ar, &depth_temp, &rect);
depth_close = view3d_depth_near(&depth_temp);
- if (depth_temp.depths) MEM_freeN(depth_temp.depths);
+ MEM_SAFE_FREE(depth_temp.depths);
return depth_close;
}
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 46ea52054c5..ae429289ffd 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -1181,14 +1181,14 @@ static short selectbuffer_ret_hits_15(unsigned int *UNUSED(buffer), const short
static short selectbuffer_ret_hits_9(unsigned int *buffer, const short hits15, const short hits9)
{
const int offs = 4 * hits15;
- memcpy(buffer, buffer + offs, 4 * offs);
+ memcpy(buffer, buffer + offs, 4 * hits9);
return hits9;
}
static short selectbuffer_ret_hits_5(unsigned int *buffer, const short hits15, const short hits9, const short hits5)
{
const int offs = 4 * hits15 + 4 * hits9;
- memcpy(buffer, buffer + offs, 4 * offs);
+ memcpy(buffer, buffer + offs, 4 * hits5);
return hits5;
}
@@ -1522,7 +1522,7 @@ static bool mouse_select(bContext *C, const int mval[2],
}
}
}
- else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) {
+ else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle, do_nearest)) {
/* then bone is found */
/* we make the armature selected:
@@ -1972,7 +1972,7 @@ static int do_armature_box_select(ViewContext *vc, rcti *rect, bool select, bool
ED_armature_sync_selection(arm->edbo);
- return OPERATOR_CANCELLED;
+ return hits > 0 ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend)
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 7bdf39d6768..c54948b23c6 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -961,7 +961,7 @@ static int walkApply(bContext *C, WalkInfo *walk)
/* clamp the angle limits */
/* it ranges from 90.0f to -90.0f */
- angle = -asin(rv3d->viewmat[2][2]);
+ angle = -asinf(rv3d->viewmat[2][2]);
if (angle > WALK_TOP_LIMIT && y > 0.0f)
y = 0.0f;
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 008022a9859..24499688835 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -58,6 +58,7 @@
#include "BKE_particle.h"
#include "BKE_unit.h"
#include "BKE_mask.h"
+#include "BKE_report.h"
#include "BIF_gl.h"
#include "BIF_glutil.h"
@@ -270,7 +271,8 @@ void convertViewVec(TransInfo *t, float r_vec[3], int dx, int dy)
r_vec[0] = dx;
r_vec[1] = dy;
}
- else { const float mval_f[2] = {(float)dx, (float)dy};
+ else {
+ const float mval_f[2] = {(float)dx, (float)dy};
ED_view3d_win_to_delta(t->ar, mval_f, r_vec, t->zfac);
}
}
@@ -2053,7 +2055,6 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
initTransInfo(C, t, op, event);
if (t->spacetype == SPACE_VIEW3D) {
- //calc_manipulator_stats(curarea);
initTransformOrientation(C, t);
t->draw_handle_apply = ED_region_draw_cb_activate(t->ar->type, drawTransformApply, t, REGION_DRAW_PRE_VIEW);
@@ -4066,6 +4067,9 @@ static void initTranslation(TransInfo *t)
{
if (t->spacetype == SPACE_ACTION) {
/* this space uses time translate */
+ BKE_report(t->reports, RPT_ERROR,
+ "Use 'Time_Translate' transform mode instead of 'Translation' mode "
+ "for translating keyframes in Dope Sheet Editor");
t->state = TRANS_CANCEL;
}
diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h
index 012f9185d8b..67d55639528 100644
--- a/source/blender/editors/transform/transform.h
+++ b/source/blender/editors/transform/transform.h
@@ -537,7 +537,6 @@ void restoreBones(TransInfo *t);
/*********************** exported from transform_manipulator.c ********** */
bool gimbal_axis(struct Object *ob, float gmat[3][3]); /* return 0 when no gimbal for selection */
-int calc_manipulator_stats(const struct bContext *C);
/*********************** TransData Creation and General Handling *********** */
void createTransData(struct bContext *C, TransInfo *t);
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index aa215613841..47adbb6d16d 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -1711,7 +1711,9 @@ static void createTransLatticeVerts(TransInfo *t)
if (bp->f1 & SELECT) {
td->flag = TD_SELECTED;
}
- else td->flag = 0;
+ else {
+ td->flag = 0;
+ }
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
@@ -3068,10 +3070,10 @@ static void createTransNlaData(bContext *C, TransInfo *t)
/* ********************* ACTION EDITOR ****************** */
-static int gpf_cmp_frame(void *thunk, void *a, void *b)
+static int gpf_cmp_frame(void *thunk, const void *a, const void *b)
{
- bGPDframe *frame_a = a;
- bGPDframe *frame_b = b;
+ const bGPDframe *frame_a = a;
+ const bGPDframe *frame_b = b;
if (frame_a->framenum < frame_b->framenum) return -1;
if (frame_a->framenum > frame_b->framenum) return 1;
@@ -3085,10 +3087,10 @@ static int gpf_cmp_frame(void *thunk, void *a, void *b)
return 0;
}
-static int masklay_shape_cmp_frame(void *thunk, void *a, void *b)
+static int masklay_shape_cmp_frame(void *thunk, const void *a, const void *b)
{
- MaskLayerShape *frame_a = a;
- MaskLayerShape *frame_b = b;
+ const MaskLayerShape *frame_a = a;
+ const MaskLayerShape *frame_b = b;
if (frame_a->frame < frame_b->frame) return -1;
if (frame_a->frame > frame_b->frame) return 1;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 2161e52d7b2..37a6d50e149 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -262,7 +262,7 @@ bool gimbal_axis(Object *ob, float gmat[3][3])
/* centroid, boundbox, of selection */
/* returns total items selected */
-int calc_manipulator_stats(const bContext *C)
+static int calc_manipulator_stats(const bContext *C)
{
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index abef2c9fc30..af563f71376 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -872,9 +872,9 @@ static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3])
cross_v3_v3v3(tmp, start, end);
if (dot_v3v3(tmp, axis) < 0.0f)
- angle = -acos(dot_v3v3(start, end));
+ angle = -acosf(dot_v3v3(start, end));
else
- angle = acos(dot_v3v3(start, end));
+ angle = acosf(dot_v3v3(start, end));
}
else {
float mtx[3][3];
@@ -884,7 +884,7 @@ static float RotationBetween(TransInfo *t, const float p1[3], const float p2[3])
mul_m3_v3(mtx, end);
mul_m3_v3(mtx, start);
- angle = atan2(start[1], start[0]) - atan2(end[1], end[0]);
+ angle = atan2f(start[1], start[0]) - atan2f(end[1], end[0]);
}
if (angle > (float)M_PI) {
@@ -2036,10 +2036,10 @@ bool snapObjectsRayEx(Scene *scene, Base *base_act, View3D *v3d, ARegion *ar, Ob
/******************** PEELING *********************************/
-static int cmpPeel(void *arg1, void *arg2)
+static int cmpPeel(const void *arg1, const void *arg2)
{
- DepthPeel *p1 = arg1;
- DepthPeel *p2 = arg2;
+ const DepthPeel *p1 = arg1;
+ const DepthPeel *p2 = arg2;
int val = 0;
if (p1->depth < p2->depth) {
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 36c96a8d011..83fd7e6505d 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -946,14 +946,30 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit)
glPointSize(1.0);
}
+
+static void draw_uv_shadows_get(SpaceImage *sima, Object *ob, Object *obedit, bool *show_shadow, bool *show_texpaint)
+{
+ *show_shadow = *show_texpaint = false;
+
+ if (ED_space_image_show_render(sima) || (sima->flag & SI_NO_DRAW_TEXPAINT))
+ return;
+
+ if ((sima->mode == SI_MODE_PAINT) && obedit && obedit->type == OB_MESH) {
+ struct BMEditMesh *em = BKE_editmesh_from_object(obedit);
+
+ *show_shadow = EDBM_mtexpoly_check(em);
+ }
+
+ *show_texpaint = (ob && ob->type == OB_MESH && ob->mode == OB_MODE_TEXTURE_PAINT);
+}
+
void draw_uvedit_main(SpaceImage *sima, ARegion *ar, Scene *scene, Object *obedit, Object *obact)
{
ToolSettings *toolsettings = scene->toolsettings;
- int show_uvedit, show_uvshadow, show_texpaint_uvshadow;
+ bool show_uvedit, show_uvshadow, show_texpaint_uvshadow;
- show_texpaint_uvshadow = ED_space_image_show_texpaint(sima, obact);
show_uvedit = ED_space_image_show_uvedit(sima, obedit);
- show_uvshadow = ED_space_image_show_uvshadow(sima, obedit);
+ draw_uv_shadows_get(sima, obact, obedit, &show_uvshadow, &show_texpaint_uvshadow);
if (show_uvedit || show_uvshadow || show_texpaint_uvshadow) {
if (show_uvshadow)
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index 5f22a201600..79f53e1d971 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -372,7 +372,7 @@ static float p_vec_angle(float *v1, float *v2, float *v3)
else if (dot >= 1.0f)
return 0.0f;
else
- return (float)acos(dot);
+ return acosf(dot);
}
static float p_vec2_angle(float *v1, float *v2, float *v3)
@@ -433,7 +433,7 @@ static float p_edge_length(PEdge *e)
d[1] = v2->co[1] - v1->co[1];
d[2] = v2->co[2] - v1->co[2];
- return sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
+ return sqrtf(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);
}
static float p_edge_uv_length(PEdge *e)
@@ -444,7 +444,7 @@ static float p_edge_uv_length(PEdge *e)
d[0] = v2->uv[0] - v1->uv[0];
d[1] = v2->uv[1] - v1->uv[1];
- return sqrt(d[0] * d[0] + d[1] * d[1]);
+ return sqrtf(d[0] * d[0] + d[1] * d[1]);
}
static void p_chart_uv_bbox(PChart *chart, float minv[2], float maxv[2])
@@ -2353,8 +2353,8 @@ static void p_abf_compute_sines(PAbfSystem *sys)
float *sine = sys->sine, *cosine = sys->cosine, *alpha = sys->alpha;
for (i = 0; i < sys->nangles; i++, sine++, cosine++, alpha++) {
- *sine = sin(*alpha);
- *cosine = cos(*alpha);
+ *sine = sinf(*alpha);
+ *cosine = cosf(*alpha);
}
}
@@ -3163,9 +3163,9 @@ static PBool p_chart_lscm_solve(PHandle *handle, PChart *chart)
SWAP(PVert *, v2, v3);
}
- sina1 = sin(a1);
- sina2 = sin(a2);
- sina3 = sin(a3);
+ sina1 = sinf(a1);
+ sina2 = sinf(a2);
+ sina3 = sinf(a3);
sinmax = max_fff(sina1, sina2, sina3);
@@ -3314,7 +3314,7 @@ static float p_face_stretch(PFace *f)
a = dot_v3v3(Ps, Ps);
c = dot_v3v3(Pt, Pt);
- T = sqrt(0.5f * (a + c));
+ T = sqrtf(0.5f * (a + c));
if (f->flag & PFACE_FILLED)
T *= 0.2f;
@@ -3630,8 +3630,8 @@ static float p_chart_minimum_area_angle(PChart *chart)
static void p_chart_rotate_minimum_area(PChart *chart)
{
float angle = p_chart_minimum_area_angle(chart);
- float sine = sin(angle);
- float cosine = cos(angle);
+ float sine = sinf(angle);
+ float cosine = cosf(angle);
PVert *v;
for (v = chart->verts; v; v = v->nextlink) {
@@ -4045,7 +4045,7 @@ static void p_smooth(PChart *chart)
diff[0] = p[0] - oldp[0];
diff[1] = p[1] - oldp[1];
- length = sqrt(diff[0] * diff[0] + diff[1] * diff[1]);
+ length = len_v2(diff);
d = max_ff(d, length);
moved += length;
}
@@ -4559,7 +4559,7 @@ void param_pack(ParamHandle *handle, float margin, bool do_rotate)
box->index = i; /* warning this index skips PCHART_NOPACK boxes */
if (margin > 0.0f)
- area += sqrt(box->w * box->h);
+ area += sqrtf(box->w * box->h);
}
if (margin > 0.0f) {
@@ -4661,7 +4661,7 @@ void param_average(ParamHandle *handle)
/* Move center to 0,0 */
p_chart_uv_translate(chart, trans);
- p_chart_uv_scale(chart, sqrt(fac / tot_fac));
+ p_chart_uv_scale(chart, sqrtf(fac / tot_fac));
/* Move to original center */
trans[0] = -trans[0];
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index ba4b65f4ed4..fcd5267fd44 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -1360,7 +1360,7 @@ static unsigned int uv_edge_hash(const void *key)
BLI_ghashutil_uinthash(edge->uv1);
}
-static int uv_edge_compare(const void *a, const void *b)
+static bool uv_edge_compare(const void *a, const void *b)
{
UvEdge *edge1 = (UvEdge *)a;
UvEdge *edge2 = (UvEdge *)b;
diff --git a/source/blender/freestyle/CMakeLists.txt b/source/blender/freestyle/CMakeLists.txt
index c94a5ac9f92..bfd1c17df7d 100644
--- a/source/blender/freestyle/CMakeLists.txt
+++ b/source/blender/freestyle/CMakeLists.txt
@@ -412,6 +412,8 @@ set(SRC
intern/scene_graph/OrientedLineRep.h
intern/scene_graph/Rep.cpp
intern/scene_graph/Rep.h
+ intern/scene_graph/SceneHash.cpp
+ intern/scene_graph/SceneHash.h
intern/scene_graph/ScenePrettyPrinter.cpp
intern/scene_graph/ScenePrettyPrinter.h
intern/scene_graph/SceneVisitor.cpp
diff --git a/source/blender/freestyle/FRS_freestyle.h b/source/blender/freestyle/FRS_freestyle.h
index fc9fc35e410..9766372507b 100644
--- a/source/blender/freestyle/FRS_freestyle.h
+++ b/source/blender/freestyle/FRS_freestyle.h
@@ -48,6 +48,7 @@ int FRS_is_freestyle_enabled(struct SceneRenderLayer *srl);
void FRS_init_stroke_rendering(struct Render *re);
struct Render *FRS_do_stroke_rendering(struct Render *re, struct SceneRenderLayer *srl, int render);
void FRS_finish_stroke_rendering(struct Render *re);
+void FRS_free_view_map_cache(void);
void FRS_composite_result(struct Render *re, struct SceneRenderLayer *srl, struct Render *freestyle_render);
void FRS_exit(void);
diff --git a/source/blender/freestyle/intern/application/Controller.cpp b/source/blender/freestyle/intern/application/Controller.cpp
index 176199600ac..7ecb4164caf 100644
--- a/source/blender/freestyle/intern/application/Controller.cpp
+++ b/source/blender/freestyle/intern/application/Controller.cpp
@@ -118,6 +118,7 @@ Controller::Controller()
_Canvas = new AppCanvas;
_inter = new PythonInterpreter();
+ _EnableViewMapCache = false;
_EnableQI = true;
_EnableFaceSmoothness = false;
_ComputeRidges = true;
@@ -126,6 +127,7 @@ Controller::Controller()
_ComputeMaterialBoundaries = true;
_sphereRadius = 1.0;
_creaseAngle = 134.43;
+ prevSceneHash = -1.0;
init_options();
}
@@ -212,6 +214,19 @@ void Controller::setContext(bContext *C)
py_inter->setContext(C);
}
+bool Controller::hitViewMapCache()
+{
+ if (!_EnableViewMapCache) {
+ return false;
+ }
+ real hashCode = sceneHashFunc.getValue();
+ if (prevSceneHash == hashCode) {
+ return (NULL != _ViewMap);
+ }
+ prevSceneHash = hashCode;
+ return false;
+}
+
int Controller::LoadMesh(Render *re, SceneRenderLayer *srl)
{
BlenderFileLoader loader(re, srl);
@@ -242,6 +257,7 @@ int Controller::LoadMesh(Render *re, SceneRenderLayer *srl)
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "Scene loaded" << endl;
printf("Mesh cleaning : %lf\n", duration);
+ printf("View map cache : %s\n", _EnableViewMapCache ? "enabled" : "disabled");
}
_SceneNumFaces += loader.numFacesRead();
@@ -263,6 +279,22 @@ int Controller::LoadMesh(Render *re, SceneRenderLayer *srl)
if (_pRenderMonitor->testBreak())
return 0;
+ if (_EnableViewMapCache) {
+ sceneHashFunc.reset();
+ blenderScene->accept(sceneHashFunc);
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ printf("Scene hash : %.16e\n", sceneHashFunc.getValue());
+ }
+ if (hitViewMapCache()) {
+ ClearRootNode();
+ return 0;
+ }
+ else {
+ delete _ViewMap;
+ _ViewMap = NULL;
+ }
+ }
+
_Chrono.start();
WXEdgeBuilder wx_builder;
@@ -357,7 +389,7 @@ void Controller::DeleteWingedEdge()
_minEdgeSize = DBL_MAX;
}
-void Controller::DeleteViewMap()
+void Controller::DeleteViewMap(bool freeCache)
{
_pView->DetachSilhouette();
if (NULL != _SilhouetteNode) {
@@ -387,14 +419,20 @@ void Controller::DeleteViewMap()
_pView->DetachDebug();
if (NULL != _DebugNode) {
- int ref = _DebugNode->destroy();
+ int ref = _DebugNode->destroy();
if (0 == ref)
_DebugNode->addRef();
}
if (NULL != _ViewMap) {
- delete _ViewMap;
- _ViewMap = NULL;
+ if (freeCache || !_EnableViewMapCache) {
+ delete _ViewMap;
+ _ViewMap = NULL;
+ prevSceneHash = -1.0;
+ }
+ else {
+ _ViewMap->Clean();
+ }
}
}
@@ -403,40 +441,7 @@ void Controller::ComputeViewMap()
if (!_ListOfModels.size())
return;
- if (NULL != _ViewMap) {
- delete _ViewMap;
- _ViewMap = NULL;
- }
-
- _pView->DetachDebug();
- if (NULL != _DebugNode) {
- int ref = _DebugNode->destroy();
- if (0 == ref)
- _DebugNode->addRef();
- }
-
- _pView->DetachSilhouette();
- if (NULL != _SilhouetteNode) {
- int ref = _SilhouetteNode->destroy();
- if (0 == ref)
- delete _SilhouetteNode;
- }
-
-#if 0
- if (NULL != _ProjectedSilhouette) {
- int ref = _ProjectedSilhouette->destroy();
- if (0 == ref)
- delete _ProjectedSilhouette;
- }
-
- if (NULL != _VisibleProjectedSilhouette) {
- int ref = _VisibleProjectedSilhouette->destroy();
- if (0 == ref) {
- delete _VisibleProjectedSilhouette;
- _VisibleProjectedSilhouette = NULL;
- }
- }
-#endif
+ DeleteViewMap(true);
// retrieve the 3D viewpoint and transformations information
//----------------------------------------------------------
@@ -763,6 +768,16 @@ int Controller::getVisibilityAlgo()
return FREESTYLE_ALGO_ADAPTIVE_TRADITIONAL;
}
+void Controller::setViewMapCache(bool iBool)
+{
+ _EnableViewMapCache = iBool;
+}
+
+bool Controller::getViewMapCache() const
+{
+ return _EnableViewMapCache;
+}
+
void Controller::setQuantitativeInvisibility(bool iBool)
{
_EnableQI = iBool;
diff --git a/source/blender/freestyle/intern/application/Controller.h b/source/blender/freestyle/intern/application/Controller.h
index f5e50347d0f..9fe57d92cf4 100644
--- a/source/blender/freestyle/intern/application/Controller.h
+++ b/source/blender/freestyle/intern/application/Controller.h
@@ -32,6 +32,7 @@
//#include "ConfigIO.h"
#include "../geometry/FastGrid.h"
+#include "../scene_graph/SceneHash.h"
#include "../system/Interpreter.h"
#include "../system/ProgressBar.h"
#include "../system/Precision.h"
@@ -96,7 +97,7 @@ public:
void Clear();
void ClearRootNode();
void DeleteWingedEdge();
- void DeleteViewMap();
+ void DeleteViewMap(bool freeCache = false);
void toggleLayer(unsigned index, bool iDisplay);
void setModified(unsigned index, bool iMod);
void resetModified(bool iMod=false);
@@ -118,6 +119,8 @@ public:
void setVisibilityAlgo(int algo);
int getVisibilityAlgo();
+ void setViewMapCache(bool iBool);
+ bool getViewMapCache() const;
void setQuantitativeInvisibility(bool iBool); // if true, we compute quantitativeInvisibility
bool getQuantitativeInvisibility() const;
void setFaceSmoothness(bool iBool);
@@ -144,6 +147,8 @@ public:
void setModulesDir(const string& dir);
string getModulesDir() const;
+ bool hitViewMapCache();
+
void resetInterpreter();
public:
@@ -231,6 +236,7 @@ private:
string _help_index;
string _browser_cmd;
+ bool _EnableViewMapCache;
bool _EnableQI;
bool _EnableFaceSmoothness;
bool _ComputeRidges;
@@ -244,6 +250,9 @@ private:
FEdgeXDetector edgeDetector;
+ SceneHash sceneHashFunc;
+ real prevSceneHash;
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Controller")
#endif
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 32f49d48ee7..4dd4598cc91 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -474,6 +474,9 @@ static void prepare(Main *bmain, Render *re, SceneRenderLayer *srl)
cout << " Z = " << (z ? "enabled" : "disabled") << endl;
}
+ if (controller->hitViewMapCache())
+ return;
+
// compute view map
re->i.infostr = "Freestyle: View map creation";
re->stats_draw(re->sdh, &re->i);
@@ -589,6 +592,7 @@ Render *FRS_do_stroke_rendering(Render *re, SceneRenderLayer *srl, int render)
RenderMonitor monitor(re);
controller->setRenderMonitor(&monitor);
+ controller->setViewMapCache((srl->freestyleConfig.flags & FREESTYLE_VIEW_MAP_CACHE) ? true : false);
if (G.debug & G_DEBUG_FREESTYLE) {
cout << endl;
@@ -647,6 +651,17 @@ void FRS_finish_stroke_rendering(Render *re)
controller->Clear();
}
+void FRS_free_view_map_cache(void)
+{
+ // free cache
+ controller->DeleteViewMap(true);
+#if 0
+ if (G.debug & G_DEBUG_FREESTYLE) {
+ printf("View map cache freed\n");
+ }
+#endif
+}
+
//=======================================================
// Freestyle Panel Configuration
//=======================================================
diff --git a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
index 15cc4c3a0b0..4d0d140474a 100644
--- a/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
+++ b/source/blender/freestyle/intern/python/BPy_FrsMaterial.cpp
@@ -80,9 +80,9 @@ PyDoc_STRVAR(FrsMaterial_doc,
" :arg emission: The emissive color.\n"
" :type emission: :class:`mathutils.Vector`, list or tuple of 4 float values\n"
" :arg shininess: The shininess coefficient.\n"
-" :type shininess: :class:float\n"
+" :type shininess: float\n"
" :arg priority: The line color priority.\n"
-" :type priority: :class:int");
+" :type priority: int");
static int FrsMaterial_init(BPy_FrsMaterial *self, PyObject *args, PyObject *kwds)
{
@@ -311,7 +311,7 @@ void FrsMaterial_mathutils_register_callback()
PyDoc_STRVAR(FrsMaterial_line_doc,
"RGBA components of the line color of the material.\n"
"\n"
-":type: mathutils.Vector");
+":type: :class:`mathutils.Vector`");
static PyObject *FrsMaterial_line_get(BPy_FrsMaterial *self, void *UNUSED(closure))
{
@@ -333,7 +333,7 @@ static int FrsMaterial_line_set(BPy_FrsMaterial *self, PyObject *value, void *UN
PyDoc_STRVAR(FrsMaterial_diffuse_doc,
"RGBA components of the diffuse color of the material.\n"
"\n"
-":type: mathutils.Vector");
+":type: :class:`mathutils.Vector`");
static PyObject *FrsMaterial_diffuse_get(BPy_FrsMaterial *self, void *UNUSED(closure))
{
@@ -355,7 +355,7 @@ static int FrsMaterial_diffuse_set(BPy_FrsMaterial *self, PyObject *value, void
PyDoc_STRVAR(FrsMaterial_specular_doc,
"RGBA components of the specular color of the material.\n"
"\n"
-":type: mathutils.Vector");
+":type: :class:`mathutils.Vector`");
static PyObject *FrsMaterial_specular_get(BPy_FrsMaterial *self, void *UNUSED(closure))
{
@@ -377,7 +377,7 @@ static int FrsMaterial_specular_set(BPy_FrsMaterial *self, PyObject *value, void
PyDoc_STRVAR(FrsMaterial_ambient_doc,
"RGBA components of the ambient color of the material.\n"
"\n"
-":type: mathutils.Color");
+":type: :class:`mathutils.Color`");
static PyObject *FrsMaterial_ambient_get(BPy_FrsMaterial *self, void *UNUSED(closure))
{
@@ -399,7 +399,7 @@ static int FrsMaterial_ambient_set(BPy_FrsMaterial *self, PyObject *value, void
PyDoc_STRVAR(FrsMaterial_emission_doc,
"RGBA components of the emissive color of the material.\n"
"\n"
-":type: mathutils.Color");
+":type: :class:`mathutils.Color`");
static PyObject *FrsMaterial_emission_get(BPy_FrsMaterial *self, void *UNUSED(closure))
{
diff --git a/source/blender/freestyle/intern/python/BPy_Interface0D.cpp b/source/blender/freestyle/intern/python/BPy_Interface0D.cpp
index 9355c9cd677..8f23800fb7a 100644
--- a/source/blender/freestyle/intern/python/BPy_Interface0D.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Interface0D.cpp
@@ -165,7 +165,7 @@ static PyObject *Interface0D_name_get(BPy_Interface0D *self, void *UNUSED(closur
PyDoc_STRVAR(Interface0D_point_3d_doc,
"The 3D point of this 0D element.\n"
"\n"
-":type: mathutils.Vector");
+":type: :class:`mathutils.Vector`");
static PyObject *Interface0D_point_3d_get(BPy_Interface0D *self, void *UNUSED(closure))
{
@@ -217,7 +217,7 @@ static PyObject *Interface0D_projected_z_get(BPy_Interface0D *self, void *UNUSED
PyDoc_STRVAR(Interface0D_point_2d_doc,
"The 2D point of this 0D element.\n"
"\n"
-":type: mathutils.Vector");
+":type: :class:`mathutils.Vector`");
static PyObject *Interface0D_point_2d_get(BPy_Interface0D *self, void *UNUSED(closure))
{
diff --git a/source/blender/freestyle/intern/python/BPy_Operators.cpp b/source/blender/freestyle/intern/python/BPy_Operators.cpp
index 123fbab7b30..d3cb44f5903 100644
--- a/source/blender/freestyle/intern/python/BPy_Operators.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Operators.cpp
@@ -74,7 +74,7 @@ PyDoc_STRVAR(Operators_select_doc,
" condition.\n"
"\n"
" :arg pred: The predicate expressing this condition.\n"
-" :type pred: UnaryPredicate1D");
+" :type pred: :class:`UnaryPredicate1D`");
static PyObject *Operators_select(BPy_Operators *self, PyObject *args, PyObject *kwds)
{
@@ -372,7 +372,7 @@ PyDoc_STRVAR(Operators_recursive_split_doc,
" condition. This predicate is evaluated for each curve before it\n"
" actually gets split. If pred_1d(chain) is true, the curve won't be\n"
" split anymore.\n"
-" :type pred: :class:`UnaryPredicate1D`\n"
+" :type pred_1d: :class:`UnaryPredicate1D`\n"
" :arg sampling: The resolution used to sample the chain for the\n"
" predicates evaluation. (The chain is not actually resampled, a\n"
" virtual point only progresses along the curve using this\n"
@@ -404,7 +404,7 @@ PyDoc_STRVAR(Operators_recursive_split_doc,
" condition. This predicate is evaluated for each curve before it\n"
" actually gets split. If pred_1d(chain) is true, the curve won't be\n"
" split anymore.\n"
-" :type pred: :class:`UnaryPredicate1D`\n"
+" :type pred_1d: :class:`UnaryPredicate1D`\n"
" :arg sampling: The resolution used to sample the chain for the\n"
" predicates evaluation. (The chain is not actually resampled; a\n"
" virtual point only progresses along the curve using this\n"
@@ -484,7 +484,7 @@ PyDoc_STRVAR(Operators_sort_doc,
" comparison predicate given as argument.\n"
"\n"
" :arg pred: The binary predicate used for the comparison.\n"
-" :type pred: BinaryPredicate1D");
+" :type pred: :class:`BinaryPredicate1D`");
static PyObject *Operators_sort(BPy_Operators *self, PyObject *args, PyObject *kwds)
{
@@ -515,7 +515,7 @@ PyDoc_STRVAR(Operators_create_doc,
" transform as a stroke.\n"
" :type pred: :class:`UnaryPredicate1D`\n"
" :arg shaders: The list of shaders used to shade the strokes.\n"
-" :type shaders: List of StrokeShader objects");
+" :type shaders: list of :class:`StrokeShader` objects");
static PyObject *Operators_create(BPy_Operators *self, PyObject *args, PyObject *kwds)
{
@@ -548,6 +548,30 @@ static PyObject *Operators_create(BPy_Operators *self, PyObject *args, PyObject
Py_RETURN_NONE;
}
+PyDoc_STRVAR(Operators_reset_doc,
+".. staticmethod:: reset(delete_strokes=True)\n"
+"\n"
+" Resets the line stylization process to the initial state. The results of\n"
+" stroke creation are accumulated if **delete_strokes** is set to False.\n"
+"\n"
+" :arg delete_strokes: Delete the strokes that are currently stored.\n"
+" :type delete_strokes: bool\n");
+
+static PyObject *Operators_reset(BPy_Operators *self, PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"delete_strokes", NULL};
+ PyObject *obj1 = 0;
+ if (PyArg_ParseTupleAndKeywords(args, kwds, "|O!", (char **)kwlist, &PyBool_Type, &obj1)) {
+ // true is the default
+ Operators::reset(obj1 ? bool_from_PyBool(obj1) : true);
+ }
+ else {
+ PyErr_SetString(PyExc_RuntimeError, "Operators.reset() failed");
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
PyDoc_STRVAR(Operators_get_viewedge_from_index_doc,
".. staticmethod:: get_viewedge_from_index(i)\n"
"\n"
@@ -671,6 +695,7 @@ static PyMethodDef BPy_Operators_methods[] = {
Operators_recursive_split_doc},
{"sort", (PyCFunction) Operators_sort, METH_VARARGS | METH_KEYWORDS | METH_STATIC, Operators_sort_doc},
{"create", (PyCFunction) Operators_create, METH_VARARGS | METH_KEYWORDS | METH_STATIC, Operators_create_doc},
+ {"reset", (PyCFunction) Operators_reset, METH_VARARGS | METH_KEYWORDS | METH_STATIC, Operators_reset_doc},
{"get_viewedge_from_index", (PyCFunction) Operators_get_viewedge_from_index,
METH_VARARGS | METH_KEYWORDS | METH_STATIC, Operators_get_viewedge_from_index_doc},
{"get_chain_from_index", (PyCFunction) Operators_get_chain_from_index, METH_VARARGS | METH_KEYWORDS | METH_STATIC,
diff --git a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
index 22ffdedb3d9..43313ef5213 100644
--- a/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
+++ b/source/blender/freestyle/intern/python/BPy_StrokeAttribute.cpp
@@ -515,7 +515,7 @@ static int StrokeAttribute_alpha_set(BPy_StrokeAttribute *self, PyObject *value,
PyDoc_STRVAR(StrokeAttribute_color_doc,
"RGB components of the stroke color.\n"
"\n"
-":type: mathutils.Color");
+":type: :class:`mathutils.Color`");
static PyObject *StrokeAttribute_color_get(BPy_StrokeAttribute *self, void *UNUSED(closure))
{
@@ -539,7 +539,7 @@ PyDoc_STRVAR(StrokeAttribute_thickness_doc,
"The right (left) component is the thickness on the right (left) of the vertex\n"
"when following the stroke.\n"
"\n"
-":type: mathutils.Vector");
+":type: :class:`mathutils.Vector`");
static PyObject *StrokeAttribute_thickness_get(BPy_StrokeAttribute *self, void *UNUSED(closure))
{
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp
index 67cf28eb7cb..8fa87166c7d 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_FalseBP1D.cpp
@@ -33,16 +33,16 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char FalseBP1D___doc__[] =
-"Class hierarchy: :class:`BinaryPredicate1D` > :class:`FalseBP1D`\n"
+"Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > :class:`FalseBP1D`\n"
"\n"
".. method:: __call__(inter1, inter2)\n"
"\n"
" Always returns false.\n"
"\n"
" :arg inter1: The first Interface1D object.\n"
-" :type inter1: :class:`Interface1D`\n"
+" :type inter1: :class:`freestyle.types.Interface1D`\n"
" :arg inter2: The second Interface1D object.\n"
-" :type inter2: :class:`Interface1D`\n"
+" :type inter2: :class:`freestyle.types.Interface1D`\n"
" :return: False.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp
index 155cc29502b..8a0a4ded58d 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_Length2DBP1D.cpp
@@ -33,7 +33,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char Length2DBP1D___doc__[] =
-"Class hierarchy: :class:`BinaryPredicate1D` > :class:`Length2DBP1D`\n"
+"Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > :class:`Length2DBP1D`\n"
"\n"
".. method:: __call__(inter1, inter2)\n"
"\n"
@@ -41,9 +41,9 @@ static char Length2DBP1D___doc__[] =
" of inter2.\n"
"\n"
" :arg inter1: The first Interface1D object.\n"
-" :type inter1: :class:`Interface1D`\n"
+" :type inter1: :class:`freestyle.types.Interface1D`\n"
" :arg inter2: The second Interface1D object.\n"
-" :type inter2: :class:`Interface1D`\n"
+" :type inter2: :class:`freestyle.types.Interface1D`\n"
" :return: True or false.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp
index 77147745389..b4a256e6f66 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_SameShapeIdBP1D.cpp
@@ -33,16 +33,16 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char SameShapeIdBP1D___doc__[] =
-"Class hierarchy: :class:`BinaryPredicate1D` > :class:`SameShapeIdBP1D`\n"
+"Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > :class:`SameShapeIdBP1D`\n"
"\n"
".. method:: __call__(inter1, inter2)\n"
"\n"
" Returns true if inter1 and inter2 belong to the same shape.\n"
"\n"
" :arg inter1: The first Interface1D object.\n"
-" :type inter1: :class:`Interface1D`\n"
+" :type inter1: :class:`freestyle.types.Interface1D`\n"
" :arg inter2: The second Interface1D object.\n"
-" :type inter2: :class:`Interface1D`\n"
+" :type inter2: :class:`freestyle.types.Interface1D`\n"
" :return: True or false.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp
index f7d702da28d..6306905b4aa 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_TrueBP1D.cpp
@@ -33,16 +33,16 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char TrueBP1D___doc__[] =
-"Class hierarchy: :class:`BinaryPredicate1D` > :class:`TrueBP1D`\n"
+"Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > :class:`TrueBP1D`\n"
"\n"
".. method:: __call__(inter1, inter2)\n"
"\n"
" Always returns true.\n"
"\n"
" :arg inter1: The first Interface1D object.\n"
-" :type inter1: :class:`Interface1D`\n"
+" :type inter1: :class:`freestyle.types.Interface1D`\n"
" :arg inter2: The second Interface1D object.\n"
-" :type inter2: :class:`Interface1D`\n"
+" :type inter2: :class:`freestyle.types.Interface1D`\n"
" :return: True.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp
index f029e434988..2072faa43ef 100644
--- a/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp
+++ b/source/blender/freestyle/intern/python/BinaryPredicate1D/BPy_ViewMapGradientNormBP1D.cpp
@@ -38,7 +38,7 @@ extern "C" {
//ViewMapGradientNormBP1D(int level, IntegrationType iType=MEAN, float sampling=2.0)
static char ViewMapGradientNormBP1D___doc__[] =
-"Class hierarchy: :class:`BinaryPredicate1D` > :class:`ViewMapGradientNormBP1D`\n"
+"Class hierarchy: :class:`freestyle.types.BinaryPredicate1D` > :class:`ViewMapGradientNormBP1D`\n"
"\n"
".. method:: __init__(level, integration_type=IntegrationType.MEAN, sampling=2.0)\n"
"\n"
@@ -49,7 +49,7 @@ static char ViewMapGradientNormBP1D___doc__[] =
" :type level: int\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
" :arg sampling: The resolution used to sample the chain:\n"
" GetViewMapGradientNormF0D is evaluated at each sample point and\n"
" the result is obtained by combining the resulting values into a\n"
@@ -62,9 +62,9 @@ static char ViewMapGradientNormBP1D___doc__[] =
" higher for inter1 than for inter2.\n"
"\n"
" :arg inter1: The first Interface1D object.\n"
-" :type inter1: :class:`Interface1D`\n"
+" :type inter1: :class:`freestyle.types.Interface1D`\n"
" :arg inter2: The second Interface1D object.\n"
-" :type inter2: :class:`Interface1D`\n"
+" :type inter2: :class:`freestyle.types.Interface1D`\n"
" :return: True or false.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
index 65d80283fca..ae4fe0764b6 100644
--- a/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
+++ b/source/blender/freestyle/intern/python/Interface0D/CurvePoint/BPy_StrokeVertex.cpp
@@ -226,7 +226,7 @@ void StrokeVertex_mathutils_register_callback()
PyDoc_STRVAR(StrokeVertex_attribute_doc,
"StrokeAttribute for this StrokeVertex.\n"
"\n"
-":type: StrokeAttribute");
+":type: :class:`StrokeAttribute`");
static PyObject *StrokeVertex_attribute_get(BPy_StrokeVertex *self, void *UNUSED(closure))
{
@@ -267,7 +267,7 @@ static int StrokeVertex_curvilinear_abscissa_set(BPy_StrokeVertex *self, PyObjec
PyDoc_STRVAR(StrokeVertex_point_doc,
"2D point coordinates.\n"
"\n"
-":type: mathutils.Vector");
+":type: :class:`mathutils.Vector`");
static PyObject *StrokeVertex_point_get(BPy_StrokeVertex *self, void *UNUSED(closure))
{
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
index 99ac72db028..6e253b7bf5d 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainPredicateIterator.cpp
@@ -38,7 +38,10 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
PyDoc_STRVAR(ChainPredicateIterator_doc,
-"Class hierarchy: :class:`Iterator` > :class:`ViewEdgeIterator` > :class:`ChainingIterator` > "
+
+"Class hierarchy: :class:`freestyle.types.Iterator` >\n"
+":class:`freestyle.types.ViewEdgeIterator` >\n"
+":class:`freestyle.types.ChainingIterator` >\n"
":class:`ChainPredicateIterator`\n"
"\n"
"A \"generic\" user-controlled ViewEdge iterator. This iterator is in\n"
@@ -63,7 +66,7 @@ PyDoc_STRVAR(ChainPredicateIterator_doc,
" already been chained must be ignored ot not.\n"
" :type restrict_to_unvisited: bool\n"
" :arg begin: The ViewEdge from where to start the iteration.\n"
-" :type begin: :class:`ViewEdge` or None\n"
+" :type begin: :class:`freestyle.types.ViewEdge` or None\n"
" :arg orientation: If true, we'll look for the next ViewEdge among\n"
" the ViewEdges that surround the ending ViewVertex of begin. If\n"
" false, we'll search over the ViewEdges surrounding the ending\n"
@@ -77,10 +80,10 @@ PyDoc_STRVAR(ChainPredicateIterator_doc,
" predicate, a starting ViewEdge and its orientation.\n"
"\n"
" :arg upred: The unary predicate that the next ViewEdge must satisfy.\n"
-" :type upred: :class:`UnaryPredicate1D`\n"
+" :type upred: :class:`freestyle.types.UnaryPredicate1D`\n"
" :arg bpred: The binary predicate that the next ViewEdge must\n"
" satisfy together with the actual pointed ViewEdge.\n"
-" :type bpred: :class:`BinaryPredicate1D`\n"
+" :type bpred: :class:`freestyle.types.BinaryPredicate1D`\n"
" :arg restrict_to_selection: Indicates whether to force the chaining\n"
" to stay within the set of selected ViewEdges or not.\n"
" :type restrict_to_selection: bool\n"
@@ -88,7 +91,7 @@ PyDoc_STRVAR(ChainPredicateIterator_doc,
" already been chained must be ignored ot not.\n"
" :type restrict_to_unvisited: bool\n"
" :arg begin: The ViewEdge from where to start the iteration.\n"
-" :type begin: :class:`ViewEdge` or None\n"
+" :type begin: :class:`freestyle.types.ViewEdge` or None\n"
" :arg orientation: If true, we'll look for the next ViewEdge among\n"
" the ViewEdges that surround the ending ViewVertex of begin. If\n"
" false, we'll search over the ViewEdges surrounding the ending\n"
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
index 1a082ac93bb..08cfffec860 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_ChainSilhouetteIterator.cpp
@@ -39,7 +39,9 @@ extern "C" {
// ChainSilhouetteIterator (const ChainSilhouetteIterator &brother)
PyDoc_STRVAR(ChainSilhouetteIterator_doc,
-"Class hierarchy: :class:`Iterator` > :class:`ViewEdgeIterator` > :class:`ChainingIterator` > "
+"Class hierarchy: :class:`freestyle.types.Iterator` >\n"
+":class:`freestyle.types.ViewEdgeIterator` >\n"
+":class:`freestyle.types.ChainingIterator` >\n"
":class:`ChainSilhouetteIterator`\n"
"\n"
"A ViewEdge Iterator used to follow ViewEdges the most naturally. For\n"
@@ -58,7 +60,7 @@ PyDoc_STRVAR(ChainSilhouetteIterator_doc,
" to stay within the set of selected ViewEdges or not.\n"
" :type restrict_to_selection: bool\n"
" :arg begin: The ViewEdge from where to start the iteration.\n"
-" :type begin: :class:`ViewEdge` or None\n"
+" :type begin: :class:`freestyle.types.ViewEdge` or None\n"
" :arg orientation: If true, we'll look for the next ViewEdge among\n"
" the ViewEdges that surround the ending ViewVertex of begin. If\n"
" false, we'll search over the ViewEdges surrounding the ending\n"
diff --git a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
index fca4c979bbb..c972db1e680 100644
--- a/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
+++ b/source/blender/freestyle/intern/python/Iterator/BPy_Interface0DIterator.cpp
@@ -138,8 +138,8 @@ static PyObject *Interface0DIterator_iternext(BPy_Interface0DIterator *self)
PyDoc_STRVAR(Interface0DIterator_object_doc,
"The 0D object currently pointed to by this iterator. Note that the object\n"
"may be an instance of an Interface0D subclass. For example if the iterator\n"
-"has been created from :method:`Stroke.vertices_begin`, the .object property\n"
-"refers to a :class:`StrokeVertex` object.\n"
+"has been created from the `vertices_begin()` method of the :class:`Stroke`\n"
+"class, the .object property refers to a :class:`StrokeVertex` object.\n"
"\n"
":type: :class:`Interface0D` or one of its subclasses.");
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp
index 045377e747e..26b83791585 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BackboneStretcherShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char BackboneStretcherShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`BackboneStretcherShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`BackboneStretcherShader`\n"
"\n"
"[Geometry shader]\n"
"\n"
@@ -52,7 +52,7 @@ static char BackboneStretcherShader___doc__[] =
" respective directions: v(1)v(0) and v(n-1)v(n).\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int BackboneStretcherShader___init__(BPy_BackboneStretcherShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp
index 002d6798df9..df076e0453a 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BezierCurveShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char BezierCurveShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`BezierCurveShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`BezierCurveShader`\n"
"\n"
"[Geometry shader]\n"
"\n"
@@ -54,7 +54,7 @@ static char BezierCurveShader___doc__[] =
" Bezier Curve approximation of the original backbone geometry.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int BezierCurveShader___init__(BPy_BezierCurveShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
index 379fb7e1b12..0e603e00f97 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_BlenderTextureShader.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char BlenderTextureShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`BlenderTextureShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`BlenderTextureShader`\n"
"\n"
"[Texture shader]\n"
"\n"
@@ -47,7 +47,8 @@ static char BlenderTextureShader___doc__[] =
"\n"
" :arg texture: A line style texture slot or a shader node tree to define\n"
" a set of textures.\n"
-" :type texture: :class:`LineStyleTextureSlot` or :class:`ShaderNodeTree`\n"
+" :type texture: :class:`bpy.types.LineStyleTextureSlot` or\n"
+" :class:`bpy.types.ShaderNodeTree`\n"
"\n"
".. method:: shade(stroke)\n"
"\n"
@@ -55,7 +56,7 @@ static char BlenderTextureShader___doc__[] =
" simulate marks.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int BlenderTextureShader___init__(BPy_BlenderTextureShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp
index 6b0c1424d61..fb85ee5a792 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_CalligraphicShader.cpp
@@ -36,7 +36,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char CalligraphicShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`CalligraphicShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`CalligraphicShader`\n"
"\n"
"[Thickness Shader]\n"
"\n"
@@ -65,7 +65,7 @@ static char CalligraphicShader___doc__[] =
" perpendicular to this one, and an interpolation inbetween.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int CalligraphicShader___init__(BPy_CalligraphicShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
index f3b9167de09..c4ed45ec820 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorNoiseShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ColorNoiseShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`ColorNoiseShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`ColorNoiseShader`\n"
"\n"
"[Color shader]\n"
"\n"
@@ -53,7 +53,7 @@ static char ColorNoiseShader___doc__[] =
" Shader to add noise to the stroke colors.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int ColorNoiseShader___init__(BPy_ColorNoiseShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.cpp
index 183edd1f6a0..173e00b0ed8 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ColorVariationPatternShader.cpp
@@ -36,7 +36,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ColorVariationPatternShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`ColorVariationPatternShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`ColorVariationPatternShader`\n"
"\n"
"[Color shader]\n"
"\n"
@@ -57,7 +57,7 @@ static char ColorVariationPatternShader___doc__[] =
" result of the multiplication of the pattern and the original color.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int ColorVariationPatternShader___init__(BPy_ColorVariationPatternShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp
index b5607f7a7b4..6607d5798f4 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantColorShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ConstantColorShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`ConstantColorShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`ConstantColorShader`\n"
"\n"
"[Color shader]\n"
"\n"
@@ -57,7 +57,7 @@ static char ConstantColorShader___doc__[] =
" Assigns a constant color to every vertex of the Stroke.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int ConstantColorShader___init__(BPy_ConstantColorShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp
index 6bc348dd7c5..c8cc41303d8 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstantThicknessShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ConstantThicknessShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`ConstantThicknessShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`ConstantThicknessShader`\n"
"\n"
"[Thickness shader]\n"
"\n"
@@ -51,7 +51,7 @@ static char ConstantThicknessShader___doc__[] =
" Assigns an absolute constant thickness to every vertex of the Stroke.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int ConstantThicknessShader___init__(BPy_ConstantThicknessShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp
index 119ba84abd3..6e1886398b6 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ConstrainedIncreasingThicknessShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ConstrainedIncreasingThicknessShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`ConstrainedIncreasingThicknessShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`ConstrainedIncreasingThicknessShader`\n"
"\n"
"[Thickness shader]\n"
"\n"
@@ -57,7 +57,7 @@ static char ConstrainedIncreasingThicknessShader___doc__[] =
" fat short lines.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int ConstrainedIncreasingThicknessShader___init__(BPy_ConstrainedIncreasingThicknessShader *self,
PyObject *args, PyObject *kwds)
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp
index e2a9a99a392..0c9b26fa434 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_GuidingLinesShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GuidingLinesShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`GuidingLinesShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`GuidingLinesShader`\n"
"\n"
"[Geometry shader]\n"
"\n"
@@ -59,7 +59,7 @@ static char GuidingLinesShader___doc__[] =
" approximation is.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int GuidingLinesShader___init__(BPy_GuidingLinesShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp
index cec0aeba58c..1ed98d62dd9 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingColorShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char IncreasingColorShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`IncreasingColorShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`IncreasingColorShader`\n"
"\n"
"[Color shader]\n"
"\n"
@@ -67,7 +67,7 @@ static char IncreasingColorShader___doc__[] =
" between the first and the last vertex.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int IncreasingColorShader___init__(BPy_IncreasingColorShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp
index ef84b9d6fd3..c9c38a9b70a 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_IncreasingThicknessShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char IncreasingThicknessShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`IncreasingThicknessShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`IncreasingThicknessShader`\n"
"\n"
"[Thickness shader]\n"
"\n"
@@ -57,7 +57,7 @@ static char IncreasingThicknessShader___doc__[] =
" linearly interpolated from A to B.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int IncreasingThicknessShader___init__(BPy_IncreasingThicknessShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp
index f405162a918..f5df1ed929f 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_PolygonalizationShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char PolygonalizationShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`PolygonalizationShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`PolygonalizationShader`\n"
"\n"
"[Geometry shader]\n"
"\n"
@@ -58,7 +58,7 @@ static char PolygonalizationShader___doc__[] =
" error is reached.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int PolygonalizationShader___init__(BPy_PolygonalizationShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp
index 94e95362ce7..2fa7b00a3b7 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SamplingShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char SamplingShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`SamplingShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`SamplingShader`\n"
"\n"
"[Geometry shader]\n"
"\n"
@@ -51,7 +51,7 @@ static char SamplingShader___doc__[] =
" Resamples the stroke.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int SamplingShader___init__(BPy_SamplingShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
index ca69561d8e0..750dc6b9eb1 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SmoothingShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char SmoothingShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`SmoothingShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`SmoothingShader`\n"
"\n"
"[Geometry shader]\n"
"\n"
@@ -71,7 +71,7 @@ static char SmoothingShader___doc__[] =
" prevent the diffusion across corners.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int SmoothingShader___init__(BPy_SmoothingShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp
index ae96400de8f..b28c3bd0f96 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_SpatialNoiseShader.cpp
@@ -36,7 +36,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char SpatialNoiseShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`SpatialNoiseShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`SpatialNoiseShader`\n"
"\n"
"[Geometry shader]\n"
"\n"
@@ -61,7 +61,7 @@ static char SpatialNoiseShader___doc__[] =
" more noisy.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int SpatialNoiseShader___init__(BPy_SpatialNoiseShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.cpp
index 5522dd46f0a..db2807addc4 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureShader.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char StrokeTextureShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`StrokeTextureShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`StrokeTextureShader`\n"
"\n"
"[Texture shader]\n"
"\n"
@@ -49,7 +49,7 @@ static char StrokeTextureShader___doc__[] =
" :type texture_file: str\n"
" :arg medium_type: The medium type and therefore, the blending mode\n"
" that must be used for the rendering of this stroke.\n"
-" :type medium_type: :class:`MediumType`\n"
+" :type medium_type: :class:`freestyle.types.MediumType`\n"
" :arg tips: Tells whether the texture includes tips or not. If it\n"
" is the case, the texture image must respect the following format.\n"
" :type tips: bool\n"
@@ -74,7 +74,7 @@ static char StrokeTextureShader___doc__[] =
" simulate its marks system.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int StrokeTextureShader___init__(BPy_StrokeTextureShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
index 5a7657f2dad..33962f8e41a 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_StrokeTextureStepShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char StrokeTextureStepShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`StrokeTextureStepShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`StrokeTextureStepShader`\n"
"\n"
"[Texture shader]\n"
"\n"
@@ -51,7 +51,7 @@ static char StrokeTextureStepShader___doc__[] =
" Assigns a spacing factor to the texture coordinates of the Stroke.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int StrokeTextureStepShader___init__(BPy_StrokeTextureStepShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.cpp
index 11bac684cf0..78a07cb6c38 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TextureAssignerShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char TextureAssignerShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`TextureAssignerShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`TextureAssignerShader`\n"
"\n"
"[Texture shader]\n"
"\n"
@@ -67,7 +67,7 @@ static char TextureAssignerShader___doc__[] =
" * Default: `/brushes/smoothAlpha.bmp`, `Stroke.OPAQUE_MEDIUM`\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int TextureAssignerShader___init__(BPy_TextureAssignerShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
index 655a5c8fe98..acd4f4172fb 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessNoiseShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ThicknessNoiseShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`ThicknessNoiseShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`ThicknessNoiseShader`\n"
"\n"
"[Thickness shader]\n"
"\n"
@@ -53,7 +53,7 @@ static char ThicknessNoiseShader___doc__[] =
" Adds some noise to the stroke thickness.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int ThicknessNoiseShader___init__(BPy_ThicknessNoiseShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.cpp
index 1f892455b29..3196065cd34 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_ThicknessVariationPatternShader.cpp
@@ -36,7 +36,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ThicknessVariationPatternShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`ThicknessVariationPatternShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`ThicknessVariationPatternShader`\n"
"\n"
"[Thickness shader]\n"
"\n"
@@ -61,7 +61,7 @@ static char ThicknessVariationPatternShader___doc__[] =
" original thickness.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int ThicknessVariationPatternShader___init__(BPy_ThicknessVariationPatternShader *self,
PyObject *args, PyObject *kwds)
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp
index 8b04ee0886f..543cd17c01e 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_TipRemoverShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char TipRemoverShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`TipRemoverShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`TipRemoverShader`\n"
"\n"
"[Geometry shader]\n"
"\n"
@@ -52,7 +52,7 @@ static char TipRemoverShader___doc__[] =
" Removes the stroke's extremities.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int TipRemoverShader___init__(BPy_TipRemoverShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.cpp
index 0c060ef6ed9..b838cae9817 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_fstreamShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char fstreamShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`fstreamShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`fstreamShader`\n"
"\n"
"[Output shader]\n"
"\n"
@@ -51,7 +51,7 @@ static char fstreamShader___doc__[] =
" Streams the Stroke in a file.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int fstreamShader___init__(BPy_fstreamShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.cpp b/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.cpp
index daa10e1b38f..97a6ca0d39e 100644
--- a/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.cpp
+++ b/source/blender/freestyle/intern/python/StrokeShader/BPy_streamShader.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char streamShader___doc__[] =
-"Class hierarchy: :class:`StrokeShader` > :class:`streamShader`\n"
+"Class hierarchy: :class:`freestyle.types.StrokeShader` > :class:`streamShader`\n"
"\n"
"[Output shader]\n"
"\n"
@@ -48,7 +48,7 @@ static char streamShader___doc__[] =
" Streams the Stroke into stdout.\n"
"\n"
" :arg stroke: A Stroke object.\n"
-" :type stroke: :class:`Stroke`\n";
+" :type stroke: :class:`freestyle.types.Stroke`\n";
static int streamShader___init__(BPy_streamShader *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp
index e2e49116106..841338ef81c 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Id/BPy_ShapeIdF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ShapeIdF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DId` > :class:`ShapeIdF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DId` > :class:`ShapeIdF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,19 +43,20 @@ static char ShapeIdF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the :class:`Id` of the Shape the :class:`Interface0D`\n"
-" pointed by the Interface0DIterator belongs to. This evaluation can\n"
-" be ambiguous (in the case of a :class:`TVertex` for example). This\n"
+" Returns the :class:`freestyle.types.Id` of the Shape the\n"
+" :class:`freestyle.types.Interface0D` pointed by the\n"
+" Interface0DIterator belongs to. This evaluation can be ambiguous (in\n"
+" the case of a :class:`freestyle.types.TVertex` for example). This\n"
" functor tries to remove this ambiguity using the context offered by\n"
-" the 1D element to which the Interface0DIterator belongs to.\n"
-" However, there still can be problematic cases, and the user willing\n"
-" to deal with this cases in a specific way should implement its own\n"
+" the 1D element to which the Interface0DIterator belongs to. However,\n"
+" there still can be problematic cases, and the user willing to deal\n"
+" with this cases in a specific way should implement its own\n"
" getShapeIdF0D functor.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The Id of the Shape the pointed Interface0D belongs to.\n"
-" :rtype: :class:`Id`\n";
+" :rtype: :class:`freestyle.types.Id`\n";
static int ShapeIdF0D___init__(BPy_ShapeIdF0D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp
index b54ed48edc3..cbb905dcf2e 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Material/BPy_MaterialF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char MaterialF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DMaterial` > :class:`MaterialF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DMaterial` > :class:`MaterialF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -44,22 +44,22 @@ static char MaterialF0D___doc__[] =
".. method:: __call__(it)\n"
"\n"
" Returns the material of the object evaluated at the\n"
-" :class:`Interface0D` pointed by the Interface0DIterator. This\n"
-" evaluation can be ambiguous (in the case of a :class:`TVertex` for\n"
-" example. This functor tries to remove this ambiguity using the\n"
-" context offered by the 1D element to which the Interface0DIterator\n"
-" belongs to and by arbitrary choosing the material of the face that\n"
-" lies on its left when following the 1D element if there are two\n"
-" different materials on each side of the point. However, there\n"
-" still can be problematic cases, and the user willing to deal with\n"
-" this cases in a specific way should implement its own getMaterial\n"
-" functor.\n"
+" :class:`freestyle.types.Interface0D` pointed by the\n"
+" Interface0DIterator. This evaluation can be ambiguous (in the case of\n"
+" a :class:`freestyle.types.TVertex` for example. This functor tries to\n"
+" remove this ambiguity using the context offered by the 1D element to\n"
+" which the Interface0DIterator belongs to and by arbitrary choosing the\n"
+" material of the face that lies on its left when following the 1D\n"
+" element if there are two different materials on each side of the\n"
+" point. However, there still can be problematic cases, and the user\n"
+" willing to deal with this cases in a specific way should implement its\n"
+" own getMaterial functor.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The material of the object evaluated at the pointed\n"
" Interface0D.\n"
-" :rtype: :class:`Material`\n";
+" :rtype: :class:`freestyle.types.Material`\n";
static int MaterialF0D___init__(BPy_MaterialF0D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp
index 63c32655da3..41ce2f5d197 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Nature_EdgeNature/BPy_CurveNatureF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char CurveNatureF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DEdgeNature` > :class:`CurveNatureF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DEdgeNature` > :class:`CurveNatureF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,14 +43,14 @@ static char CurveNatureF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the :class:`Nature` of the 1D element the Interface0D pointed\n"
-" by the Interface0DIterator belongs to.\n"
+" Returns the :class:`freestyle.types.Nature` of the 1D element the\n"
+" Interface0D pointed by the Interface0DIterator belongs to.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The nature of the 1D element to which the pointed Interface0D\n"
" belongs.\n"
-" :rtype: :class:`Nature`\n";
+" :rtype: :class:`freestyle.types.Nature`\n";
static int CurveNatureF0D___init__(BPy_CurveNatureF0D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp
index 10152f594c9..bfe060bc046 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_Normal2DF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char Normal2DF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DVec2f` > :class:`Normal2DF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DVec2f` > :class:`Normal2DF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -44,12 +44,12 @@ static char Normal2DF0D___doc__[] =
".. method:: __call__(it)\n"
"\n"
" Returns a two-dimensional vector giving the normalized 2D normal to\n"
-" the 1D element to which the :class:`Interface0D` pointed by the\n"
-" Interface0DIterator belongs. The normal is evaluated at the pointed\n"
-" Interface0D.\n"
+" the 1D element to which the :class:`freestyle.types.Interface0D`\n"
+" pointed by the Interface0DIterator belongs. The normal is evaluated\n"
+" at the pointed Interface0D.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The 2D normal of the 1D element evaluated at the pointed\n"
" Interface0D.\n"
" :rtype: :class:`mathutils.Vector`\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp
index a97b53451c7..70d122bd97a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec2f/BPy_VertexOrientation2DF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char VertexOrientation2DF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DVec2f` > :class:`VertexOrientation2DF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DVec2f` > :class:`VertexOrientation2DF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,13 +43,13 @@ static char VertexOrientation2DF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns a two-dimensional vector giving the 2D oriented tangent to\n"
-" the 1D element to which the :class:`Interface0D` pointed by the\n"
-" Interface0DIterator belongs. The 2D oriented tangent is evaluated\n"
-" at the pointed Interface0D.\n"
+" Returns a two-dimensional vector giving the 2D oriented tangent to the\n"
+" 1D element to which the :class:`freestyle.types.Interface0D` pointed\n"
+" by the Interface0DIterator belongs. The 2D oriented tangent is\n"
+" evaluated at the pointed Interface0D.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The 2D oriented tangent to the 1D element evaluated at the\n"
" pointed Interface0D.\n"
" :rtype: :class:`mathutils.Vector`\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp
index ffa8996f9b2..6b010af4228 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_Vec3f/BPy_VertexOrientation3DF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char VertexOrientation3DF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DVec3f` > :class:`VertexOrientation3DF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DVec3f` > :class:`VertexOrientation3DF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,13 +43,13 @@ static char VertexOrientation3DF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns a three-dimensional vector giving the 3D oriented tangent\n"
-" to the 1D element to which the :class:`Interface0D` pointed by the\n"
-" Interface0DIterator belongs. The 3D oriented tangent is evaluated\n"
-" at the pointed Interface0D.\n"
+" Returns a three-dimensional vector giving the 3D oriented tangent to\n"
+" the 1D element to which the :class:`freestyle.types.Interface0D`\n"
+" pointed by the Interface0DIterator belongs. The 3D oriented tangent\n"
+" is evaluated at the pointed Interface0D.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The 3D oriented tangent to the 1D element evaluated at the\n"
" pointed Interface0D.\n"
" :rtype: :class:`mathutils.Vector`\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp
index 3523b08982a..ba16fec1539 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetOccludeeF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetOccludeeF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DViewShape` > :class:`GetOccludeeF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DViewShape` > :class:`GetOccludeeF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,13 +43,13 @@ static char GetOccludeeF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the :class:`ViewShape` that the Interface0D pointed by the\n"
-" Interface0DIterator occludes.\n"
+" Returns the :class:`freestyle.types.ViewShape` that the Interface0D\n"
+" pointed by the Interface0DIterator occludes.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The ViewShape occluded by the pointed Interface0D.\n"
-" :rtype: :class:`ViewShape`\n";
+" :rtype: :class:`freestyle.types.ViewShape`\n";
static int GetOccludeeF0D___init__(BPy_GetOccludeeF0D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp
index 234dc648ff5..5e4111de924 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_ViewShape/BPy_GetShapeF0D.cpp
@@ -35,21 +35,21 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetShapeF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DViewShape` > :class:`GetShapeF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DViewShape` > :class:`GetShapeF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
-" Builds a GetShapeF0D.cpp object.\n"
+" Builds a GetShapeF0D object.\n"
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the :class:`ViewShape` containing the Interface0D pointed\n"
-" by the Interface0DIterator.\n"
+" Returns the :class:`freestyle.types.ViewShape` containing the\n"
+" Interface0D pointed by the Interface0DIterator.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The ViewShape containing the pointed Interface0D.\n"
-" :rtype: :class:`ViewShape`\n";
+" :rtype: :class:`freestyle.types.ViewShape`\n";
static int GetShapeF0D___init__(BPy_GetShapeF0D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp
index 3d343762b8e..55f7bab3bb3 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_Curvature2DAngleF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char Curvature2DAngleF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DDouble` > :class:`Curvature2DAngleF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DDouble` > :class:`Curvature2DAngleF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,13 +43,13 @@ static char Curvature2DAngleF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns a real value giving the 2D curvature (as an angle) of the\n"
-" 1D element to which the :class:`Interface0D` pointed by the\n"
-" Interface0DIterator belongs. The 2D curvature is evaluated at the\n"
+" Returns a real value giving the 2D curvature (as an angle) of the 1D\n"
+" element to which the :class:`freestyle.types.Interface0D` pointed by\n"
+" the Interface0DIterator belongs. The 2D curvature is evaluated at the\n"
" Interface0D.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The 2D curvature of the 1D element evaluated at the\n"
" pointed Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp
index 84a3fd79608..2aac3f4f1f0 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_DensityF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char DensityF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DDouble` > :class:`DensityF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DDouble` > :class:`DensityF0D`\n"
"\n"
".. method:: __init__(sigma=2.0)\n"
"\n"
@@ -49,12 +49,13 @@ static char DensityF0D___doc__[] =
".. method:: __call__(it)\n"
"\n"
" Returns the density of the (result) image evaluated at the\n"
-" :class:`Interface0D` pointed by the Interface0DIterator. This\n"
-" density is evaluated using a pixels square window around the\n"
-" evaluation point and integrating these values using a gaussian.\n"
+" :class:`freestyle.types.Interface0D` pointed by the\n"
+" Interface0DIterator. This density is evaluated using a pixels square\n"
+" window around the evaluation point and integrating these values using\n"
+" a gaussian.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The density of the image evaluated at the pointed\n"
" Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp
index d901b245247..123772b3fc7 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedXF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetProjectedXF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DDouble` > :class:`GetProjectedXF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DDouble` > :class:`GetProjectedXF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,11 +43,11 @@ static char GetProjectedXF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the X 3D projected coordinate of the :class:`Interface0D`\n"
+" Returns the X 3D projected coordinate of the :class:`freestyle.types.Interface0D`\n"
" pointed by the Interface0DIterator.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The X 3D projected coordinate of the pointed Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp
index 2d82182f011..f4e3d6ba76f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedYF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetProjectedYF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DDouble` > :class:`GetProjectedYF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DDouble` > :class:`GetProjectedYF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,11 +43,11 @@ static char GetProjectedYF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the Y 3D projected coordinate of the :class:`Interface0D`\n"
+" Returns the Y 3D projected coordinate of the :class:`freestyle.types.Interface0D`\n"
" pointed by the Interface0DIterator.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The Y 3D projected coordinate of the pointed Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp
index 9766985954b..116bb75fc55 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetProjectedZF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetProjectedZF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DDouble` > :class:`GetProjectedZF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DDouble` > :class:`GetProjectedZF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,11 +43,11 @@ static char GetProjectedZF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the Z 3D projected coordinate of the :class:`Interface0D`\n"
+" Returns the Z 3D projected coordinate of the :class:`freestyle.types.Interface0D`\n"
" pointed by the Interface0DIterator.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The Z 3D projected coordinate of the pointed Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp
index 9ee87c63bdd..614e92cf7c2 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetXF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetXF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DDouble` > :class:`GetXF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DDouble` > :class:`GetXF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,11 +43,11 @@ static char GetXF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the X 3D coordinate of the :class:`Interface0D` pointed by\n"
+" Returns the X 3D coordinate of the :class:`freestyle.types.Interface0D` pointed by\n"
" the Interface0DIterator.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The X 3D coordinate of the pointed Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp
index 90f8f74e989..1a953b9ebca 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetYF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetYF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DDouble` > :class:`GetYF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DDouble` > :class:`GetYF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,11 +43,11 @@ static char GetYF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the Y 3D coordinate of the :class:`Interface0D` pointed by\n"
+" Returns the Y 3D coordinate of the :class:`freestyle.types.Interface0D` pointed by\n"
" the Interface0DIterator.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The Y 3D coordinate of the pointed Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp
index 8876f2200c2..c985e0f5c99 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_GetZF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetZF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DDouble` > :class:`GetZF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DDouble` > :class:`GetZF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,11 +43,11 @@ static char GetZF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the Z 3D coordinate of the :class:`Interface0D` pointed by\n"
+" Returns the Z 3D coordinate of the :class:`freestyle.types.Interface0D` pointed by\n"
" the Interface0DIterator.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The Z 3D coordinate of the pointed Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp
index af5edb4eac7..3c7f3b412fe 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_LocalAverageDepthF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char LocalAverageDepthF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DDouble` > :class:`LocalAverageDepthF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DDouble` > :class:`LocalAverageDepthF0D`\n"
"\n"
".. method:: __init__(mask_size=5.0)\n"
"\n"
@@ -46,12 +46,13 @@ static char LocalAverageDepthF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the average depth around the :class:`Interface0D` pointed\n"
-" by the Interface0DIterator. The result is obtained by querying the\n"
-" depth buffer on a window around that point.\n"
+" Returns the average depth around the\n"
+" :class:`freestyle.types.Interface0D` pointed by the\n"
+" Interface0DIterator. The result is obtained by querying the depth\n"
+" buffer on a window around that point.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The average depth around the pointed Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp
index b64f6c06e93..f0c58352f4a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_double/BPy_ZDiscontinuityF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ZDiscontinuityF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DDouble` > :class:`ZDiscontinuityF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DDouble` > :class:`ZDiscontinuityF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -44,14 +44,14 @@ static char ZDiscontinuityF0D___doc__[] =
".. method:: __call__(it)\n"
"\n"
" Returns a real value giving the distance between the\n"
-" :class:`Interface0D` pointed by the Interface0DIterator and the\n"
-" shape that lies behind (occludee). This distance is evaluated in\n"
-" the camera space and normalized between 0 and 1. Therefore, if no\n"
-" object is occluded by the shape to which the Interface0D belongs to,\n"
-" 1 is returned.\n"
+" :class:`freestyle.types.Interface0D` pointed by the\n"
+" Interface0DIterator and the shape that lies behind (occludee). This\n"
+" distance is evaluated in the camera space and normalized between 0 and\n"
+" 1. Therefore, if no object is occluded by the shape to which the\n"
+" Interface0D belongs to, 1 is returned.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The normalized distance between the pointed Interface0D\n"
" and the occludee.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp
index 96db3ca7375..a2358e6ebae 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetCurvilinearAbscissaF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetCurvilinearAbscissaF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DFloat` > :class:`GetCurvilinearAbscissaF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DFloat` > :class:`GetCurvilinearAbscissaF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,12 +43,12 @@ static char GetCurvilinearAbscissaF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the curvilinear abscissa of the :class:`Interface0D`\n"
-" pointed by the Interface0DIterator in the context of its 1D\n"
-" element.\n"
+" Returns the curvilinear abscissa of the\n"
+" :class:`freestyle.types.Interface0D` pointed by the\n"
+" Interface0DIterator in the context of its 1D element.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The curvilinear abscissa of the pointed Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp
index 045a5041b9c..43061747398 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetParameterF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetParameterF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DFloat` > :class:`GetParameterF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DFloat` > :class:`GetParameterF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,11 +43,11 @@ static char GetParameterF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the parameter of the :class:`Interface0D` pointed by the\n"
-" Interface0DIterator in the context of its 1D element.\n"
+" Returns the parameter of the :class:`freestyle.types.Interface0D`\n"
+" pointed by the Interface0DIterator in the context of its 1D element.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The parameter of an Interface0D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp
index 43aebe8c4ec..cecec01dcb5 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_GetViewMapGradientNormF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetViewMapGradientNormF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DFloat` > :class:`GetViewMapGradientNormF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DFloat` > :class:`GetViewMapGradientNormF0D`\n"
"\n"
".. method:: __init__(level)\n"
"\n"
@@ -51,7 +51,7 @@ static char GetViewMapGradientNormF0D___doc__[] =
" image.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The norm of the gradient of the global viewmap density\n"
" image.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp
index c1f316a45d3..313826f9307 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadCompleteViewMapPixelF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ReadCompleteViewMapPixelF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DFloat` > :class:`ReadCompleteViewMapPixelF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DFloat` > :class:`ReadCompleteViewMapPixelF0D`\n"
"\n"
".. method:: __init__(level)\n"
"\n"
@@ -50,7 +50,7 @@ static char ReadCompleteViewMapPixelF0D___doc__[] =
" Reads a pixel in one of the level of the complete viewmap.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: A pixel in one of the level of the complete viewmap.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp
index a5c8c0c3b04..8bfccf4c80a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadMapPixelF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ReadMapPixelF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DFloat` > :class:`ReadMapPixelF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DFloat` > :class:`ReadMapPixelF0D`\n"
"\n"
".. method:: __init__(map_name, level)\n"
"\n"
@@ -52,7 +52,7 @@ static char ReadMapPixelF0D___doc__[] =
" Reads a pixel in a map.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: A pixel in a map.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp
index e46d9f316eb..b36ddf84e71 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_float/BPy_ReadSteerableViewMapPixelF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ReadSteerableViewMapPixelF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DFloat` > :class:`ReadSteerableViewMapPixelF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DFloat` > :class:`ReadSteerableViewMapPixelF0D`\n"
"\n"
".. method:: __init__(orientation, level)\n"
"\n"
@@ -53,7 +53,7 @@ static char ReadSteerableViewMapPixelF0D___doc__[] =
" Reads a pixel in one of the level of one of the steerable viewmaps.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: A pixel in one of the level of one of the steerable viewmaps.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp
index bcd17213c55..8ec982815c8 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_unsigned_int/BPy_QuantitativeInvisibilityF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char QuantitativeInvisibilityF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DUnsigned` > :class:`QuantitativeInvisibilityF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DUnsigned` > :class:`QuantitativeInvisibilityF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,17 +43,17 @@ static char QuantitativeInvisibilityF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns the quantitative invisibility of the :class:`Interface0D`\n"
-" pointed by the Interface0DIterator. This evaluation can be\n"
-" ambiguous (in the case of a :class:`TVertex` for example). This\n"
-" functor tries to remove this ambiguity using the context offered by\n"
-" the 1D element to which the Interface0D belongs to. However, there\n"
-" still can be problematic cases, and the user willing to deal with\n"
-" this cases in a specific way should implement its own getQIF0D\n"
-" functor.\n"
+" Returns the quantitative invisibility of the\n"
+" :class:`freestyle.types.Interface0D` pointed by the\n"
+" Interface0DIterator. This evaluation can be ambiguous (in the case of\n"
+" a :class:`freestyle.types.TVertex` for example). This functor tries\n"
+" to remove this ambiguity using the context offered by the 1D element\n"
+" to which the Interface0D belongs to. However, there still can be\n"
+" problematic cases, and the user willing to deal with this cases in a\n"
+" specific way should implement its own getQIF0D functor.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: The quantitative invisibility of the pointed Interface0D.\n"
" :rtype: int\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp
index e6dce989822..5504bff74ae 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction0D/UnaryFunction0D_vector_ViewShape/BPy_GetOccludersF0D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetOccludersF0D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction0D` > :class:`UnaryFunction0DVectorViewShape` > :class:`GetOccludersF0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction0D` > :class:`freestyle.types.UnaryFunction0DVectorViewShape` > :class:`GetOccludersF0D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -43,14 +43,14 @@ static char GetOccludersF0D___doc__[] =
"\n"
".. method:: __call__(it)\n"
"\n"
-" Returns a list of :class:`ViewShape` objects occluding the\n"
-" :class:`Interface0D` pointed by the Interface0DIterator.\n"
+" Returns a list of :class:`freestyle.types.ViewShape` objects occluding the\n"
+" :class:`freestyle.types.Interface0D` pointed by the Interface0DIterator.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: A list of ViewShape objects occluding the pointed\n"
" Interface0D.\n"
-" :rtype: list of :class:`ViewShape` objects\n";
+" :rtype: list of :class:`freestyle.types.ViewShape` objects\n";
static int GetOccludersF0D___init__(BPy_GetOccludersF0D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp
index 70c454c2c71..55092416cc2 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Nature_EdgeNature/BPy_CurveNatureF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char CurveNatureF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DEdgeNature` > :class:`CurveNatureF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DEdgeNature` > :class:`CurveNatureF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,21 +45,22 @@ static char CurveNatureF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
-" Returns the nature of the Interface1D (silhouette, ridge, crease,\n"
-" and so on). Except if the Interface1D is a :class:`ViewEdge`, this\n"
-" result might be ambiguous. Indeed, the Interface1D might result\n"
-" from the gathering of several 1D elements, each one being of a\n"
-" different nature. An integration method, such as the MEAN, might\n"
-" give, in this case, irrelevant results.\n"
+" Returns the nature of the Interface1D (silhouette, ridge, crease, and\n"
+" so on). Except if the Interface1D is a\n"
+" :class:`freestyle.types.ViewEdge`, this result might be ambiguous.\n"
+" Indeed, the Interface1D might result from the gathering of several 1D\n"
+" elements, each one being of a different nature. An integration\n"
+" method, such as the MEAN, might give, in this case, irrelevant\n"
+" results.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The nature of the Interface1D.\n"
-" :rtype: :class:`Nature`\n";
+" :rtype: :class:`freestyle.types.Nature`\n";
static int CurveNatureF1D___init__(BPy_CurveNatureF1D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp
index 6be8b81f43f..76330c77927 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Normal2DF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char Normal2DF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DVec2f` > :class:`Normal2DF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DVec2f` > :class:`Normal2DF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,14 +45,14 @@ static char Normal2DF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Returns the 2D normal for the Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The 2D normal for the Interface1D.\n"
" :rtype: :class:`mathutils.Vector`\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp
index 01a6f8bd602..07aa9071c57 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec2f/BPy_Orientation2DF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char Orientation2DF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DVec2f` > :class:`Orientation2DF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DVec2f` > :class:`Orientation2DF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,14 +45,14 @@ static char Orientation2DF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Returns the 2D orientation of the Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The 2D orientation of the Interface1D.\n"
" :rtype: :class:`mathutils.Vector`\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp
index 4d76fb709d8..56dd67b1d2f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_Vec3f/BPy_Orientation3DF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char Orientation3DF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DVec3f` > :class:`Orientation3DF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DVec3f` > :class:`Orientation3DF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,14 +45,14 @@ static char Orientation3DF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Returns the 3D orientation of the Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The 3D orientation of the Interface1D.\n"
" :rtype: :class:`mathutils.Vector`\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp
index 4278f088863..e5779ce36e1 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_Curvature2DAngleF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char Curvature2DAngleF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`Curvature2DAngleF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`Curvature2DAngleF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,14 +45,14 @@ static char Curvature2DAngleF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Returns the 2D curvature as an angle for an Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The 2D curvature as an angle.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp
index 5beb724e9af..ffee3ec81f2 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_DensityF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char DensityF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`DensityF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`DensityF1D`\n"
"\n"
".. method:: __init__(sigma=2.0, integration_type=IntegrationType.MEAN, sampling=2.0)\n"
"\n"
@@ -48,7 +48,7 @@ static char DensityF1D___doc__[] =
" :type sigma: float\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
" :arg sampling: The resolution used to sample the chain: the\n"
" corresponding 0D function is evaluated at each sample point and\n"
" the result is obtained by combining the resulting values into a\n"
@@ -59,12 +59,12 @@ static char DensityF1D___doc__[] =
"\n"
" Returns the density evaluated for an Interface1D. The density is\n"
" evaluated for a set of points along the Interface1D (using the\n"
-" :class:`DensityF0D` functor) with a user-defined sampling and then\n"
-" integrated into a single value using a user-defined integration\n"
-" method.\n"
+" :class:`freestyle.functions.DensityF0D` functor) with a user-defined\n"
+" sampling and then integrated into a single value using a user-defined\n"
+" integration method.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The density evaluated for an Interface1D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp
index 1a0588383fc..9164032488e 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetCompleteViewMapDensityF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetCompleteViewMapDensityF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`GetCompleteViewMapDensityF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`GetCompleteViewMapDensityF1D`\n"
"\n"
".. method:: __init__(level, integration_type=IntegrationType.MEAN, sampling=2.0)\n"
"\n"
@@ -48,7 +48,7 @@ static char GetCompleteViewMapDensityF1D___doc__[] =
" :type level: int\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
" :arg sampling: The resolution used to sample the chain: the\n"
" corresponding 0D function is evaluated at each sample point and\n"
" the result is obtained by combining the resulting values into a\n"
@@ -58,13 +58,14 @@ static char GetCompleteViewMapDensityF1D___doc__[] =
".. method:: __call__(inter)\n"
"\n"
" Returns the density evaluated for an Interface1D in the complete\n"
-" viewmap image. The density is evaluated for a set of points along\n"
-" the Interface1D (using the :class:`ReadCompleteViewMapPixelF0D`\n"
-" functor) and then integrated into a single value using a\n"
-" user-defined integration method.\n"
+" viewmap image. The density is evaluated for a set of points along the\n"
+" Interface1D (using the\n"
+" :class:`freestyle.functions.ReadCompleteViewMapPixelF0D` functor) and\n"
+" then integrated into a single value using a user-defined integration\n"
+" method.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The density evaluated for the Interface1D in the complete\n"
" viewmap image.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp
index 41841a83374..517b07f5c7f 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetDirectionalViewMapDensityF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetDirectionalViewMapDensityF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` "
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` "
"> :class:`GetDirectionalViewMapDensityF1D`\n"
"\n"
".. method:: __init__(orientation, level, integration_type=IntegrationType.MEAN, sampling=2.0)\n"
@@ -52,7 +52,7 @@ static char GetDirectionalViewMapDensityF1D___doc__[] =
" :type level: int\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
" :arg sampling: The resolution used to sample the chain: the\n"
" corresponding 0D function is evaluated at each sample point and\n"
" the result is obtained by combining the resulting values into a\n"
@@ -61,15 +61,16 @@ static char GetDirectionalViewMapDensityF1D___doc__[] =
"\n"
".. method:: __call__(inter)\n"
"\n"
-" Returns the density evaluated for an Interface1D in of the\n"
-" steerable viewmaps image. The direction telling which Directional\n"
-" map to choose is explicitely specified by the user. The density is\n"
-" evaluated for a set of points along the Interface1D (using the\n"
-" :class:`ReadSteerableViewMapPixelF0D` functor) and then integrated\n"
-" into a single value using a user-defined integration method.\n"
+" Returns the density evaluated for an Interface1D in of the steerable\n"
+" viewmaps image. The direction telling which Directional map to choose\n"
+" is explicitely specified by the user. The density is evaluated for a\n"
+" set of points along the Interface1D (using the\n"
+" :class:`freestyle.functions.ReadSteerableViewMapPixelF0D` functor) and\n"
+" then integrated into a single value using a user-defined integration\n"
+" method.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: the density evaluated for an Interface1D in of the\n"
" steerable viewmaps image.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp
index 9baec0fe70a..290b43e5ea6 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedXF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetProjectedXF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`GetProjectedXF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`GetProjectedXF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,14 +45,14 @@ static char GetProjectedXF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values. \n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Returns the projected X 3D coordinate of an Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The projected X 3D coordinate of an Interface1D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp
index 004f014cc0d..7d9f7461908 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedYF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetProjectedYF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`GetProjectedYF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`GetProjectedYF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,14 +45,14 @@ static char GetProjectedYF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values. \n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Returns the projected Y 3D coordinate of an Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The projected Y 3D coordinate of an Interface1D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp
index daafe1a3b6f..b8e8cf5e57e 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetProjectedZF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetProjectedZF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`GetProjectedZF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`GetProjectedZF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,14 +45,14 @@ static char GetProjectedZF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values. \n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Returns the projected Z 3D coordinate of an Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The projected Z 3D coordinate of an Interface1D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp
index 199e437639f..c67485e7d36 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetSteerableViewMapDensityF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetSteerableViewMapDensityF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`GetSteerableViewMapDensityF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`GetSteerableViewMapDensityF1D`\n"
"\n"
".. method:: __init__(level, integration_type=IntegrationType.MEAN, sampling=2.0)\n"
"\n"
@@ -48,7 +48,7 @@ static char GetSteerableViewMapDensityF1D___doc__[] =
" :type level: int\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
" :arg sampling: The resolution used to sample the chain: the\n"
" corresponding 0D function is evaluated at each sample point and\n"
" the result is obtained by combining the resulting values into a\n"
@@ -58,11 +58,12 @@ static char GetSteerableViewMapDensityF1D___doc__[] =
".. method:: __call__(inter)\n"
"\n"
" Returns the density of the ViewMap for a given Interface1D. The\n"
-" density of each :class:`FEdge` is evaluated in the proper steerable\n"
-" :class:`ViewMap` depending on its orientation.\n"
+" density of each :class:`freestyle.types.FEdge` is evaluated in the\n"
+" proper steerable :class:`freestyle.types.ViewMap` depending on its\n"
+" orientation.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The density of the ViewMap for a given Interface1D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp
index 5c9bd76a4b3..ebcb273082e 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetViewMapGradientNormF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetViewMapGradientNormF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`GetViewMapGradientNormF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`GetViewMapGradientNormF1D`\n"
"\n"
".. method:: __init__(level, integration_type=IntegrationType.MEAN, sampling=2.0)\n"
"\n"
@@ -48,7 +48,7 @@ static char GetViewMapGradientNormF1D___doc__[] =
" :type level: int\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
" :arg sampling: The resolution used to sample the chain: the\n"
" corresponding 0D function is evaluated at each sample point and\n"
" the result is obtained by combining the resulting values into a\n"
@@ -58,11 +58,12 @@ static char GetViewMapGradientNormF1D___doc__[] =
".. method:: __call__(inter)\n"
"\n"
" Returns the density of the ViewMap for a given Interface1D. The\n"
-" density of each :class:`FEdge` is evaluated in the proper steerable\n"
-" :class:`ViewMap` depending on its orientation.\n"
+" density of each :class:`freestyle.types.FEdge` is evaluated in the\n"
+" proper steerable :class:`freestyle.types.ViewMap` depending on its\n"
+" orientation.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The density of the ViewMap for a given Interface1D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp
index fa749a05c69..b55a4a79fe9 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetXF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetXF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`GetXF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`GetXF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,14 +45,14 @@ static char GetXF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Returns the X 3D coordinate of an Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The X 3D coordinate of the Interface1D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp
index 96022997763..d760ef948f0 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetYF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetYF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`GetYF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`GetYF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,14 +45,14 @@ static char GetYF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Returns the Y 3D coordinate of an Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The Y 3D coordinate of the Interface1D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp
index 46695affe49..72a8b22630d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_GetZF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetZF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`GetZF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`GetZF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,14 +45,14 @@ static char GetZF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Returns the Z 3D coordinate of an Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The Z 3D coordinate of the Interface1D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp
index 3638908c5bd..424f08c07c0 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_LocalAverageDepthF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char LocalAverageDepthF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`LocalAverageDepthF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`LocalAverageDepthF1D`\n"
"\n"
".. method:: __init__(sigma, integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -48,18 +48,18 @@ static char LocalAverageDepthF1D___doc__[] =
" :type sigma: float\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
-" Returns the average depth evaluated for an Interface1D. The\n"
-" average depth is evaluated for a set of points along the\n"
-" Interface1D (using the :class:`LocalAverageDepthF0D` functor) with\n"
-" a user-defined sampling and then integrated into a single value\n"
-" using a user-defined integration method.\n"
+" Returns the average depth evaluated for an Interface1D. The average\n"
+" depth is evaluated for a set of points along the Interface1D (using\n"
+" the :class:`freestyle.functions.LocalAverageDepthF0D` functor) with a\n"
+" user-defined sampling and then integrated into a single value using a\n"
+" user-defined integration method.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The average depth evaluated for the Interface1D.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp
index 65fde596e23..488675142b6 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_double/BPy_ZDiscontinuityF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ZDiscontinuityF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DDouble` > :class:`ZDiscontinuityF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DDouble` > :class:`ZDiscontinuityF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,7 +45,7 @@ static char ZDiscontinuityF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
@@ -56,7 +56,7 @@ static char ZDiscontinuityF1D___doc__[] =
" Interface1D belongs to, 1 is returned.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The normalized distance between the Interface1D and the occludee.\n"
" :rtype: float\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp
index c70493e9140..a21efd655ab 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_unsigned_int/BPy_QuantitativeInvisibilityF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char QuantitativeInvisibilityF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DUnsigned` > :class:`QuantitativeInvisibilityF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DUnsigned` > :class:`QuantitativeInvisibilityF1D`\n"
"\n"
".. method:: __init__(integration_type=IntegrationType.MEAN)\n"
"\n"
@@ -45,18 +45,18 @@ static char QuantitativeInvisibilityF1D___doc__[] =
"\n"
" :arg integration_type: The integration method used to compute a single value\n"
" from a set of values.\n"
-" :type integration_type: :class:`IntegrationType`\n"
+" :type integration_type: :class:`freestyle.types.IntegrationType`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
-" Returns the Quantitative Invisibility of an Interface1D element.\n"
-" If the Interface1D is a :class:`ViewEdge`, then there is no\n"
-" ambiguity concerning the result. But, if the Interface1D results\n"
+" Returns the Quantitative Invisibility of an Interface1D element. If\n"
+" the Interface1D is a :class:`freestyle.types.ViewEdge`, then there is\n"
+" no ambiguity concerning the result. But, if the Interface1D results\n"
" of a chaining (chain, stroke), then it might be made of several 1D\n"
" elements of different Quantitative Invisibilities.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: The Quantitative Invisibility of the Interface1D.\n"
" :rtype: int\n";
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp
index d0c16f8dae2..e4e7560822d 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludeeF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetOccludeeF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DVectorViewShape` > :class:`GetOccludeeF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DVectorViewShape` > :class:`GetOccludeeF1D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -48,9 +48,9 @@ static char GetOccludeeF1D___doc__[] =
" Returns a list of occluded shapes covered by this Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: A list of occluded shapes covered by the Interface1D.\n"
-" :rtype: list of :class:`ViewShape` objects\n";
+" :rtype: list of :class:`freestyle.types.ViewShape` objects\n";
static int GetOccludeeF1D___init__(BPy_GetOccludeeF1D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp
index 62612c7cc19..ced04a5077a 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetOccludersF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetOccludersF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DVectorViewShape` > :class:`GetOccludersF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DVectorViewShape` > :class:`GetOccludersF1D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -48,9 +48,9 @@ static char GetOccludersF1D___doc__[] =
" Returns a list of occluding shapes that cover this Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: A list of occluding shapes that cover the Interface1D.\n"
-" :rtype: list of :class:`ViewShape` objects\n";
+" :rtype: list of :class:`freestyle.types.ViewShape` objects\n";
static int GetOccludersF1D___init__(BPy_GetOccludersF1D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp
index 1dab3962ec2..f26f8105a9e 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_vector_ViewShape/BPy_GetShapeF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char GetShapeF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DVectorViewShape` > :class:`GetShapeF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DVectorViewShape` > :class:`GetShapeF1D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -48,9 +48,9 @@ static char GetShapeF1D___doc__[] =
" Returns a list of shapes covered by this Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: A list of shapes covered by the Interface1D.\n"
-" :rtype: list of :class:`ViewShape` objects\n";
+" :rtype: list of :class:`freestyle.types.ViewShape` objects\n";
static int GetShapeF1D___init__(BPy_GetShapeF1D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp
index e585829ff0a..128deeccd11 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_ChainingTimeStampF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ChainingTimeStampF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DVoid` > :class:`ChainingTimeStampF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DVoid` > :class:`ChainingTimeStampF1D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -48,7 +48,7 @@ static char ChainingTimeStampF1D___doc__[] =
" Sets the chaining time stamp of the Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n";
+" :type inter: :class:`freestyle.types.Interface1D`\n";
static int ChainingTimeStampF1D___init__(BPy_ChainingTimeStampF1D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp
index 96d594ff56e..64a92a8e357 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_IncrementChainingTimeStampF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char IncrementChainingTimeStampF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DVoid` > :class:`IncrementChainingTimeStampF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DVoid` > :class:`IncrementChainingTimeStampF1D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -48,7 +48,7 @@ static char IncrementChainingTimeStampF1D___doc__[] =
" Increments the chaining time stamp of the Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n";
+" :type inter: :class:`freestyle.types.Interface1D`\n";
static int IncrementChainingTimeStampF1D___init__(BPy_IncrementChainingTimeStampF1D *self,
PyObject *args, PyObject *kwds)
diff --git a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp
index 715bbaafdba..2cd359eea61 100644
--- a/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryFunction1D/UnaryFunction1D_void/BPy_TimeStampF1D.cpp
@@ -37,7 +37,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char TimeStampF1D___doc__[] =
-"Class hierarchy: :class:`UnaryFunction1D` > :class:`UnaryFunction1DVoid` > :class:`TimeStampF1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryFunction1D` > :class:`freestyle.types.UnaryFunction1DVoid` > :class:`TimeStampF1D`\n"
"\n"
".. method:: __init__()\n"
"\n"
@@ -48,7 +48,7 @@ static char TimeStampF1D___doc__[] =
" Returns the time stamp of the Interface1D.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n";
+" :type inter: :class:`freestyle.types.Interface1D`\n";
static int TimeStampF1D___init__(BPy_TimeStampF1D *self, PyObject *args, PyObject *kwds)
{
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp
index 896348d143c..36511e01358 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_FalseUP0D.cpp
@@ -33,14 +33,14 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char FalseUP0D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate0D` > :class:`FalseUP0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate0D` > :class:`FalseUP0D`\n"
"\n"
".. method:: __call__(it)\n"
"\n"
" Always returns false.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: False.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp
index c4c157dd689..f5da320a31c 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate0D/BPy_TrueUP0D.cpp
@@ -33,14 +33,14 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char TrueUP0D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate0D` > :class:`TrueUP0D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate0D` > :class:`TrueUP0D`\n"
"\n"
".. method:: __call__(it)\n"
"\n"
" Always returns true.\n"
"\n"
" :arg it: An Interface0DIterator object.\n"
-" :type it: :class:`Interface0DIterator`\n"
+" :type it: :class:`freestyle.types.Interface0DIterator`\n"
" :return: True.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp
index 8365f9b832a..d0ced2ad4c3 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ContourUP1D.cpp
@@ -33,7 +33,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ContourUP1D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate1D` > :class:`ContourUP1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate1D` > :class:`ContourUP1D`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
@@ -41,7 +41,7 @@ static char ContourUP1D___doc__[] =
" contour if it is borded by a different shape on each of its sides.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: True if the Interface1D is a contour, false otherwise.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp
index b0bd67744c5..807d76f4731 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_DensityLowerThanUP1D.cpp
@@ -35,7 +35,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char DensityLowerThanUP1D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate1D` > :class:`DensityLowerThanUP1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate1D` > :class:`DensityLowerThanUP1D`\n"
"\n"
".. method:: __init__(threshold, sigma=2.0)\n"
"\n"
@@ -45,7 +45,7 @@ static char DensityLowerThanUP1D___doc__[] =
" having a density lower than this threshold will match.\n"
" :type threshold: float\n"
" :arg sigma: The sigma value defining the density evaluation window\n"
-" size used in the :class:`DensityF0D` functor.\n"
+" size used in the :class:`freestyle.functions.DensityF0D` functor.\n"
" :type sigma: float\n"
"\n"
".. method:: __call__(inter)\n"
@@ -54,7 +54,7 @@ static char DensityLowerThanUP1D___doc__[] =
" than a user-defined density value.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: True if the density is lower than a threshold.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp
index 5cc5e0cf12a..f8a7ff8650c 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToChainingTimeStampUP1D.cpp
@@ -33,7 +33,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char EqualToChainingTimeStampUP1D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate1D` > :class:`EqualToChainingTimeStampUP1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate1D` > :class:`freestyle.types.EqualToChainingTimeStampUP1D`\n"
"\n"
".. method:: __init__(ts)\n"
"\n"
@@ -48,7 +48,7 @@ static char EqualToChainingTimeStampUP1D___doc__[] =
" user-defined value.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: True if the time stamp is equal to a user-defined value.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp
index a2cafcf5fd2..ffed4f966e6 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_EqualToTimeStampUP1D.cpp
@@ -33,7 +33,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char EqualToTimeStampUP1D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate1D` > :class:`EqualToTimeStampUP1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate1D` > :class:`EqualToTimeStampUP1D`\n"
"\n"
".. method:: __init__(ts)\n"
"\n"
@@ -48,7 +48,7 @@ static char EqualToTimeStampUP1D___doc__[] =
" user-defined value.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: True if the time stamp is equal to a user-defined value.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp
index 486b020ef6a..140ebb86454 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ExternalContourUP1D.cpp
@@ -33,7 +33,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ExternalContourUP1D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate1D` > :class:`ExternalContourUP1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate1D` > :class:`ExternalContourUP1D`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
@@ -42,7 +42,7 @@ static char ExternalContourUP1D___doc__[] =
" one of its sides.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: True if the Interface1D is an external contour, false\n"
" otherwise.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp
index 098f449048e..2d1e99aed2b 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_FalseUP1D.cpp
@@ -33,14 +33,14 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char FalseUP1D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate1D` > :class:`FalseUP1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate1D` > :class:`FalseUP1D`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Always returns false.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: False.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp
index 143aac7d4c5..806ad8168ac 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_QuantitativeInvisibilityUP1D.cpp
@@ -33,7 +33,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char QuantitativeInvisibilityUP1D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate1D` > :class:`QuantitativeInvisibilityUP1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate1D` > :class:`QuantitativeInvisibilityUP1D`\n"
"\n"
".. method:: __init__(qi=0)\n"
"\n"
@@ -46,11 +46,12 @@ static char QuantitativeInvisibilityUP1D___doc__[] =
".. method:: __call__(inter)\n"
"\n"
" Returns true if the Quantitative Invisibility evaluated at an\n"
-" Interface1D, using the :class:`QuantitativeInvisibilityF1D`\n"
-" functor, equals a certain user-defined value.\n"
+" Interface1D, using the\n"
+" :class:`freestyle.functions.QuantitativeInvisibilityF1D` functor,\n"
+" equals a certain user-defined value.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: True if Quantitative Invisibility equals a user-defined\n"
" value.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp
index 998d6b1ed61..93970972aac 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_ShapeUP1D.cpp
@@ -33,7 +33,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char ShapeUP1D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate1D` > :class:`ShapeUP1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate1D` > :class:`ShapeUP1D`\n"
"\n"
".. method:: __init__(first, second=0)\n"
"\n"
@@ -46,11 +46,11 @@ static char ShapeUP1D___doc__[] =
"\n"
".. method:: __call__(inter)\n"
"\n"
-" Returns true if the shape to which the Interface1D belongs to has\n"
-" the same :class:`Id` as the one specified by the user.\n"
+" Returns true if the shape to which the Interface1D belongs to has the\n"
+" same :class:`freestyle.types.Id` as the one specified by the user.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: True if Interface1D belongs to the shape of the\n"
" user-specified Id.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp
index 8444fbfc365..d4ca82721d5 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_TrueUP1D.cpp
@@ -33,14 +33,14 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char TrueUP1D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate1D` > :class:`TrueUP1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate1D` > :class:`TrueUP1D`\n"
"\n"
".. method:: __call__(inter)\n"
"\n"
" Always returns true.\n"
"\n"
" :arg inter: An Interface1D object.\n"
-" :type inter: :class:`Interface1D`\n"
+" :type inter: :class:`freestyle.types.Interface1D`\n"
" :return: True.\n"
" :rtype: bool\n";
diff --git a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp
index 7e310fe593d..6f08cd1c796 100644
--- a/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp
+++ b/source/blender/freestyle/intern/python/UnaryPredicate1D/BPy_WithinImageBoundaryUP1D.cpp
@@ -33,7 +33,7 @@ extern "C" {
//------------------------INSTANCE METHODS ----------------------------------
static char WithinImageBoundaryUP1D___doc__[] =
-"Class hierarchy: :class:`UnaryPredicate1D` > :class:`WithinImageBoundaryUP1D`\n"
+"Class hierarchy: :class:`freestyle.types.UnaryPredicate1D` > :class:`WithinImageBoundaryUP1D`\n"
"\n"
".. method:: __init__(xmin, ymin, xmax, ymax)\n"
"\n"
diff --git a/source/blender/freestyle/intern/scene_graph/SceneHash.cpp b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
new file mode 100644
index 00000000000..6e8856f1b93
--- /dev/null
+++ b/source/blender/freestyle/intern/scene_graph/SceneHash.cpp
@@ -0,0 +1,39 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/freestyle/intern/scene_graph/SceneHash.cpp
+ * \ingroup freestyle
+ */
+
+#include "SceneHash.h"
+
+namespace Freestyle {
+
+void SceneHash::visitIndexedFaceSet(IndexedFaceSet& ifs)
+{
+ const real *v = ifs.vertices();
+ const unsigned n = ifs.vsize();
+
+ for (unsigned i = 0; i < n; i++) {
+ _hashcode += v[i];
+ }
+}
+
+} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/scene_graph/SceneHash.h b/source/blender/freestyle/intern/scene_graph/SceneHash.h
new file mode 100644
index 00000000000..8f5f847eaab
--- /dev/null
+++ b/source/blender/freestyle/intern/scene_graph/SceneHash.h
@@ -0,0 +1,67 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __FREESTYLE_SCENE_HASH_H__
+#define __FREESTYLE_SCENE_HASH_H__
+
+/** \file blender/freestyle/intern/scene_graph/SceneHash.h
+ * \ingroup freestyle
+ */
+
+#include "IndexedFaceSet.h"
+#include "SceneVisitor.h"
+
+#ifdef WITH_CXX_GUARDEDALLOC
+#include "MEM_guardedalloc.h"
+#endif
+
+namespace Freestyle {
+
+class SceneHash : public SceneVisitor
+{
+public:
+ inline SceneHash() : SceneVisitor()
+ {
+ _hashcode = 0.0;
+ }
+
+ virtual ~SceneHash() {}
+
+ VISIT_DECL(IndexedFaceSet)
+
+ inline real getValue() {
+ return _hashcode;
+ }
+
+ inline void reset() {
+ _hashcode = 0.0;
+ }
+
+private:
+ real _hashcode;
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SceneHash")
+#endif
+};
+
+} /* namespace Freestyle */
+
+#endif // __FREESTYLE_SCENE_HASH_H__
diff --git a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
index b7b5eb4162b..69ca45d3ec7 100644
--- a/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
+++ b/source/blender/freestyle/intern/stroke/BasicStrokeShaders.cpp
@@ -808,9 +808,10 @@ int BezierCurveShader::shade(Stroke& stroke) const
++it)
{
(it)->setAttribute(*a);
- if ((index <= index1) || (index > index2))
+ if ((index <= index1) || (index > index2)) {
++a;
- ++index;
+ }
+ ++index;
}
return 0;
}
diff --git a/source/blender/freestyle/intern/stroke/Chain.cpp b/source/blender/freestyle/intern/stroke/Chain.cpp
index 7fd756472b0..0e8c2c9ae6f 100644
--- a/source/blender/freestyle/intern/stroke/Chain.cpp
+++ b/source/blender/freestyle/intern/stroke/Chain.cpp
@@ -59,6 +59,7 @@ void Chain::push_viewedge_back(ViewEdge *iViewEdge, bool orientation)
CurvePoint *cp = _Vertices.back(); // assumed to be instantiated as new CurvePoint(iSVertex, 0, 0.f);
SVertex *sv_first = (*vfirst);
FEdge *fe = _fedgeB->duplicate();
+ fe->setTemporary(true);
fe->setVertexB(sv_first);
fe->vertexA()->shape()->AddEdge(fe);
fe->vertexA()->AddFEdge(fe);
@@ -119,6 +120,7 @@ void Chain::push_viewedge_front(ViewEdge *iViewEdge, bool orientation)
SVertex *sv_curr = (*v);
FEdge *fe = (orientation) ? iViewEdge->fedgeA() : iViewEdge->fedgeB();
FEdge *fe2 = fe->duplicate();
+ fe2->setTemporary(true);
fe2->setVertexA(sv_curr);
fe2->setVertexB(sv_last);
sv_last->AddFEdge(fe2);
diff --git a/source/blender/freestyle/intern/stroke/Chain.h b/source/blender/freestyle/intern/stroke/Chain.h
index 95e825e270b..6cf3a7199bf 100644
--- a/source/blender/freestyle/intern/stroke/Chain.h
+++ b/source/blender/freestyle/intern/stroke/Chain.h
@@ -106,6 +106,10 @@ public:
{
return _splittingId;
}
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Chain")
+#endif
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/Curve.h b/source/blender/freestyle/intern/stroke/Curve.h
index 6b799c921a4..726b238c74b 100644
--- a/source/blender/freestyle/intern/stroke/Curve.h
+++ b/source/blender/freestyle/intern/stroke/Curve.h
@@ -341,6 +341,10 @@ public:
real curvatureFredo() const;
Vec2d directionFredo() const;
#endif
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:CurvePoint")
+#endif
};
@@ -586,6 +590,10 @@ public:
* At each iteration a virtual temporary CurvePoint is created.
*/
virtual Interface0DIterator pointsEnd(float t = 0.0f);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Curve")
+#endif
};
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/Operators.cpp b/source/blender/freestyle/intern/stroke/Operators.cpp
index 427994f80f1..87ba34e8f42 100644
--- a/source/blender/freestyle/intern/stroke/Operators.cpp
+++ b/source/blender/freestyle/intern/stroke/Operators.cpp
@@ -1242,7 +1242,7 @@ error:
return -1;
}
-void Operators::reset()
+void Operators::reset(bool removeStrokes)
{
ViewMap *vm = ViewMap::getInstance();
if (!vm) {
@@ -1253,11 +1253,7 @@ void Operators::reset()
for (I1DContainer::iterator it = _current_chains_set.begin(); it != _current_chains_set.end(); ++it)
delete *it;
_current_chains_set.clear();
-#if 0
- _current_view_edges_set.insert(_current_view_edges_set.begin(),
- vm->ViewEdges().begin(),
- vm->ViewEdges().end());
-#else
+
ViewMap::viewedges_container& vedges = vm->ViewEdges();
ViewMap::viewedges_container::iterator ve = vedges.begin(), veend = vedges.end();
for (; ve != veend; ++ve) {
@@ -1265,9 +1261,9 @@ void Operators::reset()
continue;
_current_view_edges_set.push_back(*ve);
}
-#endif
_current_set = &_current_view_edges_set;
- _current_strokes_set.clear();
+ if (removeStrokes)
+ _current_strokes_set.clear();
}
} /* namespace Freestyle */
diff --git a/source/blender/freestyle/intern/stroke/Operators.h b/source/blender/freestyle/intern/stroke/Operators.h
index 59ebec57246..c7b0e3f8b81 100644
--- a/source/blender/freestyle/intern/stroke/Operators.h
+++ b/source/blender/freestyle/intern/stroke/Operators.h
@@ -259,7 +259,7 @@ public:
return &_current_strokes_set;
}
- static void reset();
+ static void reset(bool removeStrokes=true);
private:
Operators() {}
diff --git a/source/blender/freestyle/intern/stroke/Stroke.h b/source/blender/freestyle/intern/stroke/Stroke.h
index 86c667a38b6..8ff801ed144 100644
--- a/source/blender/freestyle/intern/stroke/Stroke.h
+++ b/source/blender/freestyle/intern/stroke/Stroke.h
@@ -474,6 +474,10 @@ public:
/* interface definition */
/* inherited */
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:StrokeVertex")
+#endif
};
@@ -862,6 +866,10 @@ public:
virtual Interface0DIterator pointsBegin(float t = 0.0f);
virtual Interface0DIterator pointsEnd(float t = 0.0f);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Stroke")
+#endif
};
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
index 9c9cd88f188..a5e526fc490 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.cpp
@@ -63,14 +63,14 @@ void FEdgeXDetector::processShapes(WingedEdge& we)
WXFace *wxf = dynamic_cast<WXFace*>(*wf);
wxf->Clear();
}
- _computeViewIndependant = true;
+ _computeViewIndependent = true;
}
- else if (!(wxs)->getComputeViewIndependantFlag()) {
+ else if (!(wxs)->getComputeViewIndependentFlag()) {
wxs->Reset();
- _computeViewIndependant = false;
+ _computeViewIndependent = false;
}
else {
- _computeViewIndependant = true;
+ _computeViewIndependent = true;
}
preProcessShape(wxs);
if (progressBarDisplay)
@@ -97,8 +97,8 @@ void FEdgeXDetector::processShapes(WingedEdge& we)
if (progressBarDisplay)
_pProgressBar->setProgress(_pProgressBar->getProgress() + 1);
- wxs->setComputeViewIndependantFlag(false);
- _computeViewIndependant = false;
+ wxs->setComputeViewIndependentFlag(false);
+ _computeViewIndependent = false;
_changes = false;
// reset user data
@@ -187,8 +187,8 @@ void FEdgeXDetector::computeCurvatures(WXVertex *vertex)
CurvatureInfo *C;
float radius = _sphereRadius * _meanEdgeSize;
- // view independant stuff
- if (_computeViewIndependant) {
+ // view independent stuff
+ if (_computeViewIndependent) {
C = new CurvatureInfo();
vertex->setCurvatures(C);
OGF::NormalCycle ncycle;
@@ -333,7 +333,7 @@ void FEdgeXDetector::ProcessSilhouetteEdge(WXEdge *iEdge)
/////////
void FEdgeXDetector::processBorderShape(WXShape *iWShape)
{
- if (!_computeViewIndependant)
+ if (!_computeViewIndependent)
return;
// Make a pass on the edges to detect the BORDER
vector<WEdge*>::iterator we, weend;
@@ -358,7 +358,7 @@ void FEdgeXDetector::ProcessBorderEdge(WXEdge *iEdge)
/////////
void FEdgeXDetector::processCreaseShape(WXShape *iWShape)
{
- if (!_computeViewIndependant)
+ if (!_computeViewIndependent)
return;
// Make a pass on the edges to detect the CREASE
@@ -390,7 +390,7 @@ void FEdgeXDetector::processRidgesAndValleysShape(WXShape *iWShape)
// Don't forget to add the built layer to the face at the end of the ProcessFace:
//iFace->AddSmoothLayer(faceLayer);
- if (!_computeViewIndependant)
+ if (!_computeViewIndependent)
return;
// Here the curvatures must already have been computed
@@ -684,7 +684,7 @@ void FEdgeXDetector::postProcessSuggestiveContourFace(WXFace *iFace)
////////////////////
void FEdgeXDetector::processMaterialBoundaryShape(WXShape *iWShape)
{
- if (!_computeViewIndependant)
+ if (!_computeViewIndependent)
return;
// Make a pass on the edges to detect material boundaries
vector<WEdge*>::iterator we, weend;
diff --git a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
index 8adf685a6eb..8170fc5baab 100644
--- a/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
+++ b/source/blender/freestyle/intern/view_map/FEdgeXDetector.h
@@ -57,7 +57,7 @@ public:
{
_pProgressBar = NULL;
_pRenderMonitor = NULL;
- _computeViewIndependant = true;
+ _computeViewIndependent = true;
_bbox_diagonal = 1.0;
_meanEdgeSize = 0;
_computeRidgesAndValleys = true;
@@ -213,7 +213,7 @@ protected:
Vec3r _Viewpoint;
real _bbox_diagonal; // diagonal of the current processed shape bbox
//oldtmp values
- bool _computeViewIndependant;
+ bool _computeViewIndependent;
real _meanK1;
real _meanKr;
real _minK1;
diff --git a/source/blender/freestyle/intern/view_map/Silhouette.h b/source/blender/freestyle/intern/view_map/Silhouette.h
index d838b98c1a8..94b00157ccd 100644
--- a/source/blender/freestyle/intern/view_map/Silhouette.h
+++ b/source/blender/freestyle/intern/view_map/Silhouette.h
@@ -378,6 +378,17 @@ public:
_FEdges.push_back(iFEdge);
}
+ /*! Remove an FEdge from the list of edges emanating from this SVertex. */
+ inline void RemoveFEdge(FEdge *iFEdge)
+ {
+ for (vector<FEdge *>::iterator fe = _FEdges.begin(), fend = _FEdges.end(); fe != fend; fe++) {
+ if (iFEdge == (*fe)) {
+ _FEdges.erase(fe);
+ break;
+ }
+ }
+ }
+
/* replaces edge 1 by edge 2 in the list of edges */
inline void Replace(FEdge *e1, FEdge *e2)
{
@@ -441,6 +452,10 @@ public:
/*! angle in radians */
inline real curvature2d_as_angle() const;
#endif
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SVertex")
+#endif
};
/**********************************/
@@ -518,6 +533,8 @@ protected:
bool _isInImage;
+ bool _isTemporary;
+
public:
/*! A field that can be used by the user to store any data.
* This field must be reseted afterwards using ResetUserData().
@@ -538,6 +555,7 @@ public:
_occludeeEmpty = true;
_isSmooth = false;
_isInImage = true;
+ _isTemporary = false;
}
/*! Builds an FEdge going from vA to vB. */
@@ -554,6 +572,7 @@ public:
_occludeeEmpty = true;
_isSmooth = false;
_isInImage = true;
+ _isTemporary = false;
}
/*! Copy constructor */
@@ -573,6 +592,7 @@ public:
_occludeeEmpty = iBrother._occludeeEmpty;
_isSmooth = iBrother._isSmooth;
_isInImage = iBrother._isInImage;
+ _isTemporary = iBrother._isTemporary;
iBrother.userdata = this;
userdata = 0;
}
@@ -708,6 +728,11 @@ public:
return _isInImage;
}
+ inline bool isTemporary() const
+ {
+ return _isTemporary;
+ }
+
/* modifiers */
/*! Sets the first SVertex. */
inline void setVertexA(SVertex *vA)
@@ -803,6 +828,11 @@ public:
_isInImage = iFlag;
}
+ inline void setTemporary(bool iFlag)
+ {
+ _isTemporary = iFlag;
+ }
+
/* checks whether two FEdge have a common vertex.
* Returns a pointer on the common vertex if it exists, NULL otherwise.
*/
@@ -931,6 +961,10 @@ public:
* The sampling with which we want to iterate over points of this FEdge.
*/
virtual inline Interface0DIterator pointsEnd(float t = 0.0f);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdge")
+#endif
};
//
@@ -1241,6 +1275,10 @@ public:
{
_bFaceMark = iFaceMark;
}
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeSharp")
+#endif
};
/*! Class defining a smooth edge. This kind of edge typically runs across a face of the input mesh. It can be
@@ -1353,6 +1391,10 @@ public:
{
_FrsMaterialIndex = i;
}
+
+#ifdef WITH_CXX_GUARDEDALLOC
+ MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:FEdgeSmooth")
+#endif
};
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.cpp b/source/blender/freestyle/intern/view_map/ViewMap.cpp
index fd5ebb99f72..6bb0082e379 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.cpp
+++ b/source/blender/freestyle/intern/view_map/ViewMap.cpp
@@ -63,6 +63,30 @@ ViewMap::~ViewMap()
_VEdges.clear();
}
+void ViewMap::Clean()
+{
+ vector<FEdge*> tmpEdges;
+
+ for (vector<ViewShape*>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend; vs++) {
+ vector<FEdge*>& edges = (*vs)->sshape()->getEdgeList();
+ for (vector<FEdge*>::iterator it = edges.begin(), itend = edges.end(); it != itend; it++) {
+ if ((*it)->isTemporary()) {
+ (*it)->setTemporary(false); // avoid being counted multiple times
+ tmpEdges.push_back(*it);
+ }
+ }
+ }
+
+ for (vector<FEdge*>::iterator it = tmpEdges.begin(), itend = tmpEdges.end(); it != itend; it++) {
+ for (vector<ViewShape*>::iterator vs = _VShapes.begin(), vsend = _VShapes.end(); vs != vsend; vs++) {
+ (*vs)->sshape()->RemoveEdge(*it);
+ }
+ (*it)->vertexA()->RemoveFEdge(*it);
+ (*it)->vertexB()->RemoveFEdge(*it);
+ delete (*it);
+ }
+}
+
ViewShape *ViewMap::viewShape(unsigned id)
{
int index = _shapeIdToIndex[id];
diff --git a/source/blender/freestyle/intern/view_map/ViewMap.h b/source/blender/freestyle/intern/view_map/ViewMap.h
index d87341503fa..0ee1864e086 100644
--- a/source/blender/freestyle/intern/view_map/ViewMap.h
+++ b/source/blender/freestyle/intern/view_map/ViewMap.h
@@ -236,6 +236,9 @@ public:
/* connects a FEdge to the graph trough a SVertex */
//FEdge *Connect(FEdge *ioEdge, SVertex *ioVertex);
+ /* Clean temporary FEdges created by chaining */
+ virtual void Clean();
+
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewMap")
#endif
@@ -369,7 +372,6 @@ public:
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewVertex")
#endif
-
};
/**********************************/
@@ -642,7 +644,6 @@ public:
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:TVertex")
#endif
-
};
@@ -859,7 +860,6 @@ public:
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:NonTVertex")
#endif
-
};
/**********************************/
@@ -1379,7 +1379,6 @@ public:
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:ViewEdge")
#endif
-
};
diff --git a/source/blender/freestyle/intern/winged_edge/WXEdge.h b/source/blender/freestyle/intern/winged_edge/WXEdge.h
index ce9749369fc..3c9ec7a7e3d 100644
--- a/source/blender/freestyle/intern/winged_edge/WXEdge.h
+++ b/source/blender/freestyle/intern/winged_edge/WXEdge.h
@@ -718,18 +718,18 @@ public:
typedef WXShape type_name;
protected:
- bool _computeViewIndependant; // flag to indicate whether the view independant stuff must be computed or not
+ bool _computeViewIndependent; // flag to indicate whether the view independent stuff must be computed or not
public:
inline WXShape() : WShape()
{
- _computeViewIndependant = true;
+ _computeViewIndependent = true;
}
/*! copy constructor */
inline WXShape(WXShape& iBrother) : WShape(iBrother)
{
- _computeViewIndependant = iBrother._computeViewIndependant;
+ _computeViewIndependent = iBrother._computeViewIndependent;
}
virtual WShape *duplicate()
@@ -740,14 +740,14 @@ public:
virtual ~WXShape() {}
- inline bool getComputeViewIndependantFlag() const
+ inline bool getComputeViewIndependentFlag() const
{
- return _computeViewIndependant;
+ return _computeViewIndependent;
}
- inline void setComputeViewIndependantFlag(bool iFlag)
+ inline void setComputeViewIndependentFlag(bool iFlag)
{
- _computeViewIndependant = iFlag;
+ _computeViewIndependent = iFlag;
}
/*! designed to build a specialized WFace for use in MakeFace */
diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c
index ca8997913bf..04f8e68431a 100644
--- a/source/blender/gpu/intern/gpu_extensions.c
+++ b/source/blender/gpu/intern/gpu_extensions.c
@@ -719,9 +719,12 @@ void GPU_invalid_tex_bind(int mode)
void GPU_invalid_tex_free(void)
{
- GPU_texture_free(GG.invalid_tex_1D);
- GPU_texture_free(GG.invalid_tex_2D);
- GPU_texture_free(GG.invalid_tex_3D);
+ if (GG.invalid_tex_1D)
+ GPU_texture_free(GG.invalid_tex_1D);
+ if (GG.invalid_tex_2D)
+ GPU_texture_free(GG.invalid_tex_2D);
+ if (GG.invalid_tex_3D)
+ GPU_texture_free(GG.invalid_tex_3D);
}
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 6578f4b9697..f91fd7a8c1e 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -737,8 +737,9 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la
i = is;
GPU_link(mat, "shade_visifac", i, visifac, shi->refl, &i);
- GPU_link(mat, "set_value", GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &lcol);
+ GPU_link(mat, "set_rgb", GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob), &lcol);
shade_light_textures(mat, lamp, &lcol);
+ GPU_link(mat, "shade_mul_value_v3", GPU_dynamic_uniform(&lamp->dynenergy, GPU_DYNAMIC_LAMP_DYNENERGY, lamp->ob), lcol, &lcol);
#if 0
if (ma->mode & MA_TANGENT_VN)
@@ -1714,9 +1715,9 @@ void GPU_lamp_update_colors(GPULamp *lamp, float r, float g, float b, float ener
lamp->energy = energy;
if (lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
- lamp->col[0]= r* lamp->energy;
- lamp->col[1]= g* lamp->energy;
- lamp->col[2]= b* lamp->energy;
+ lamp->col[0]= r;
+ lamp->col[1]= g;
+ lamp->col[2]= b;
}
void GPU_lamp_update_distance(GPULamp *lamp, float distance, float att1, float att2)
@@ -1748,9 +1749,9 @@ static void gpu_lamp_from_blender(Scene *scene, Object *ob, Object *par, Lamp *l
lamp->energy = la->energy;
if (lamp->mode & LA_NEG) lamp->energy= -lamp->energy;
- lamp->col[0]= la->r*lamp->energy;
- lamp->col[1]= la->g*lamp->energy;
- lamp->col[2]= la->b*lamp->energy;
+ lamp->col[0]= la->r;
+ lamp->col[1]= la->g;
+ lamp->col[2]= la->b;
GPU_lamp_update(lamp, ob->lay, (ob->restrictflag & OB_RESTRICT_RENDER), ob->obmat);
@@ -2013,6 +2014,7 @@ GPUNodeLink *GPU_lamp_get_data(GPUMaterial *mat, GPULamp *lamp, GPUNodeLink **co
*col = GPU_dynamic_uniform(lamp->dyncol, GPU_DYNAMIC_LAMP_DYNCOL, lamp->ob);
visifac = lamp_get_visibility(mat, lamp, lv, dist);
+ /* looks like it's not used? psy-fi */
shade_light_textures(mat, lamp, col);
if (GPU_lamp_has_shadow_buffer(lamp)) {
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index da92c52d62c..afd6af9efae 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -126,7 +126,7 @@ void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, rctf *input, c
}
else if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
glEnable(GL_DEPTH_TEST);
- glDepthMask(GL_TRUE);
+ glDepthMask(GL_FALSE);
glDepthFunc(GL_EQUAL);
}
}
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 3ba36c11311..23716c8105d 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1960,6 +1960,11 @@ void shade_mul_value(float fac, vec4 col, out vec4 outcol)
outcol = col*fac;
}
+void shade_mul_value_v3(float fac, vec3 col, out vec3 outcol)
+{
+ outcol = col*fac;
+}
+
void shade_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
{
outcol = vec4(col.rgb*obcol.rgb, col.a);
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index 5077ccec256..afff97a8409 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -68,7 +68,7 @@ extern "C" {
#include "itasc_plugin.h"
// default parameters
-bItasc DefIKParam;
+static bItasc DefIKParam;
// in case of animation mode, feedback and timestep is fixed
// #define ANIM_TIMESTEP 1.0
diff --git a/source/blender/imbuf/intern/cache.c b/source/blender/imbuf/intern/cache.c
index 0c17dd21434..677c3dbe700 100644
--- a/source/blender/imbuf/intern/cache.c
+++ b/source/blender/imbuf/intern/cache.c
@@ -101,14 +101,14 @@ static unsigned int imb_global_tile_hash(const void *gtile_p)
return ((unsigned int)(intptr_t)gtile->ibuf) * 769 + gtile->tx * 53 + gtile->ty * 97;
}
-static int imb_global_tile_cmp(const void *a_p, const void *b_p)
+static bool imb_global_tile_cmp(const void *a_p, const void *b_p)
{
const ImGlobalTile *a = a_p;
const ImGlobalTile *b = b_p;
- if (a->ibuf == b->ibuf && a->tx == b->tx && a->ty == b->ty) return 0;
- else if (a->ibuf < b->ibuf || a->tx < b->tx || a->ty < b->ty) return -1;
- else return 1;
+ return ((a->ibuf != b->ibuf) ||
+ (a->tx != b->tx) ||
+ (a->ty != b->ty));
}
static unsigned int imb_thread_tile_hash(const void *ttile_p)
@@ -118,14 +118,14 @@ static unsigned int imb_thread_tile_hash(const void *ttile_p)
return ((unsigned int)(intptr_t)ttile->ibuf) * 769 + ttile->tx * 53 + ttile->ty * 97;
}
-static int imb_thread_tile_cmp(const void *a_p, const void *b_p)
+static bool imb_thread_tile_cmp(const void *a_p, const void *b_p)
{
const ImThreadTile *a = a_p;
const ImThreadTile *b = b_p;
- if (a->ibuf == b->ibuf && a->tx == b->tx && a->ty == b->ty) return 0;
- else if (a->ibuf < b->ibuf || a->tx < b->tx || a->ty < b->ty) return -1;
- else return 1;
+ return ((a->ibuf != b->ibuf) ||
+ (a->tx != b->tx) ||
+ (a->ty != b->ty));
}
/******************************** Load/Unload ********************************/
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 06dd128137b..5dd6b366a93 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -252,22 +252,13 @@ static unsigned int colormanage_hashhash(const void *key_v)
return rval;
}
-static int colormanage_hashcmp(const void *av, const void *bv)
+static bool colormanage_hashcmp(const void *av, const void *bv)
{
const ColormanageCacheKey *a = (ColormanageCacheKey *) av;
const ColormanageCacheKey *b = (ColormanageCacheKey *) bv;
- if (a->view < b->view)
- return -1;
- else if (a->view > b->view)
- return 1;
-
- if (a->display < b->display)
- return -1;
- else if (a->display > b->display)
- return 1;
-
- return 0;
+ return ((a->view != b->view) ||
+ (a->display != b->display));
}
static struct MovieCache *colormanage_moviecache_ensure(ImBuf *ibuf)
diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c
index ea75673e5f0..1641bd3089b 100644
--- a/source/blender/imbuf/intern/moviecache.c
+++ b/source/blender/imbuf/intern/moviecache.c
@@ -104,7 +104,7 @@ static unsigned int moviecache_hashhash(const void *keyv)
return key->cache_owner->hashfp(key->userkey);
}
-static int moviecache_hashcmp(const void *av, const void *bv)
+static bool moviecache_hashcmp(const void *av, const void *bv)
{
const MovieCacheKey *a = (MovieCacheKey *)av;
const MovieCacheKey *b = (MovieCacheKey *)bv;
diff --git a/source/blender/imbuf/intern/readimage.c b/source/blender/imbuf/intern/readimage.c
index f0bcfcea62d..bb09c57d1e5 100644
--- a/source/blender/imbuf/intern/readimage.c
+++ b/source/blender/imbuf/intern/readimage.c
@@ -58,7 +58,7 @@ static void imb_handle_alpha(ImBuf *ibuf, int flags, char colorspace[IM_MAX_SPAC
int alpha_flags;
if (colorspace) {
- if (ibuf->rect) {
+ if (ibuf->rect != NULL && ibuf->rect_float == NULL) {
/* byte buffer is never internally converted to some standard space,
* store pointer to it's color space descriptor instead
*/
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 8483e5f08f9..33d1445fb93 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -182,7 +182,7 @@ typedef struct PreviewImage {
#define ID_CU MAKE_ID2('C', 'U') /* Curve */
#define ID_MB MAKE_ID2('M', 'B') /* MetaBall */
#define ID_MA MAKE_ID2('M', 'A') /* Material */
-#define ID_TE MAKE_ID2('T', 'E') /* Texture */
+#define ID_TE MAKE_ID2('T', 'E') /* Tex (Texture) */
#define ID_IM MAKE_ID2('I', 'M') /* Image */
#define ID_LT MAKE_ID2('L', 'T') /* Lattice */
#define ID_LA MAKE_ID2('L', 'A') /* Lamp */
@@ -192,25 +192,25 @@ typedef struct PreviewImage {
#define ID_WO MAKE_ID2('W', 'O') /* World */
#define ID_SCR MAKE_ID2('S', 'R') /* Screen */
#define ID_SCRN MAKE_ID2('S', 'N') /* (depreciated?) */
-#define ID_VF MAKE_ID2('V', 'F') /* VectorFont */
+#define ID_VF MAKE_ID2('V', 'F') /* VFont (Vector Font) */
#define ID_TXT MAKE_ID2('T', 'X') /* Text */
#define ID_SPK MAKE_ID2('S', 'K') /* Speaker */
#define ID_SO MAKE_ID2('S', 'O') /* Sound */
#define ID_GR MAKE_ID2('G', 'R') /* Group */
#define ID_ID MAKE_ID2('I', 'D') /* (internal use only) */
-#define ID_AR MAKE_ID2('A', 'R') /* Armature */
-#define ID_AC MAKE_ID2('A', 'C') /* Action */
+#define ID_AR MAKE_ID2('A', 'R') /* bArmature */
+#define ID_AC MAKE_ID2('A', 'C') /* bAction */
#define ID_SCRIPT MAKE_ID2('P', 'Y') /* Script (depreciated) */
-#define ID_NT MAKE_ID2('N', 'T') /* NodeTree */
+#define ID_NT MAKE_ID2('N', 'T') /* bNodeTree */
#define ID_BR MAKE_ID2('B', 'R') /* Brush */
#define ID_PA MAKE_ID2('P', 'A') /* ParticleSettings */
-#define ID_GD MAKE_ID2('G', 'D') /* GreasePencil */
+#define ID_GD MAKE_ID2('G', 'D') /* bGPdata, (Grease Pencil) */
#define ID_WM MAKE_ID2('W', 'M') /* WindowManager */
#define ID_MC MAKE_ID2('M', 'C') /* MovieClip */
#define ID_MSK MAKE_ID2('M', 'S') /* Mask */
#define ID_LS MAKE_ID2('L', 'S') /* FreestyleLineStyle */
#define ID_PAL MAKE_ID2('P', 'L') /* Palette */
-#define ID_PC MAKE_ID2('P', 'C') /* Paint Curve */
+#define ID_PC MAKE_ID2('P', 'C') /* PaintCurve */
/* NOTE! Fake IDs, needed for g.sipo->blocktype or outliner */
#define ID_SEQ MAKE_ID2('S', 'Q')
diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h
index 9fbd70419f4..b14861fcf47 100644
--- a/source/blender/makesdna/DNA_brush_types.h
+++ b/source/blender/makesdna/DNA_brush_types.h
@@ -153,8 +153,8 @@ typedef struct Palette
ListBase colors;
ListBase deleted;
- int num_of_colours;
int active_color;
+ int pad;
} Palette;
typedef struct PaintCurvePoint
diff --git a/source/blender/makesdna/DNA_freestyle_types.h b/source/blender/makesdna/DNA_freestyle_types.h
index 195c7eb4841..d099511a088 100644
--- a/source/blender/makesdna/DNA_freestyle_types.h
+++ b/source/blender/makesdna/DNA_freestyle_types.h
@@ -50,6 +50,7 @@ struct Text;
#define FREESTYLE_FACE_SMOOTHNESS_FLAG (1 << 3)
#define FREESTYLE_ADVANCED_OPTIONS_FLAG (1 << 4)
#define FREESTYLE_CULLING (1 << 5)
+#define FREESTYLE_VIEW_MAP_CACHE (1 << 6)
/* FreestyleConfig::mode */
#define FREESTYLE_CONTROL_SCRIPT_MODE 1
diff --git a/source/blender/makesdna/DNA_image_types.h b/source/blender/makesdna/DNA_image_types.h
index 0b9dddd0ea5..b66772f0bb9 100644
--- a/source/blender/makesdna/DNA_image_types.h
+++ b/source/blender/makesdna/DNA_image_types.h
@@ -109,6 +109,7 @@ typedef struct Image {
int gen_x, gen_y;
char gen_type, gen_flag;
short gen_depth;
+ float gen_color[4];
/* display aspect - for UV editing images resized for faster openGL display */
float aspx, aspy;
diff --git a/source/blender/makesdna/DNA_lamp_types.h b/source/blender/makesdna/DNA_lamp_types.h
index b7aae005e3b..a920182d5a3 100644
--- a/source/blender/makesdna/DNA_lamp_types.h
+++ b/source/blender/makesdna/DNA_lamp_types.h
@@ -131,26 +131,26 @@ typedef struct Lamp {
#define LA_YF_PHOTON 5
/* mode */
-#define LA_SHAD_BUF 1
-#define LA_HALO 2
-#define LA_LAYER 4
-#define LA_QUAD 8 /* no longer used */
-#define LA_NEG 16
-#define LA_ONLYSHADOW 32
-#define LA_SPHERE 64
-#define LA_SQUARE 128
-#define LA_TEXTURE 256
-#define LA_OSATEX 512
-/* #define LA_DEEP_SHADOW 1024 */ /* not used anywhere */
-#define LA_NO_DIFF 2048
-#define LA_NO_SPEC 4096
-#define LA_SHAD_RAY 8192
+#define LA_SHAD_BUF (1 << 0)
+#define LA_HALO (1 << 1)
+#define LA_LAYER (1 << 2)
+#define LA_QUAD (1 << 3) /* no longer used */
+#define LA_NEG (1 << 4)
+#define LA_ONLYSHADOW (1 << 5)
+#define LA_SPHERE (1 << 6)
+#define LA_SQUARE (1 << 7)
+#define LA_TEXTURE (1 << 8)
+#define LA_OSATEX (1 << 9)
+/* #define LA_DEEP_SHADOW (1 << 10) */ /* not used anywhere */
+#define LA_NO_DIFF (1 << 11)
+#define LA_NO_SPEC (1 << 12)
+#define LA_SHAD_RAY (1 << 13)
/* yafray: lamp shadowbuffer flag, softlight */
/* Since it is used with LOCAL lamp, can't use LA_SHAD */
-/* #define LA_YF_SOFT 16384 */ /* no longer used */
-#define LA_LAYER_SHADOW 32768
-#define LA_SHAD_TEX (1<<16)
-#define LA_SHOW_CONE (1<<17)
+/* #define LA_YF_SOFT (1 << 14) */ /* no longer used */
+#define LA_LAYER_SHADOW (1 << 15)
+#define LA_SHAD_TEX (1 << 16)
+#define LA_SHOW_CONE (1 << 17)
/* layer_shadow */
#define LA_LAYER_SHADOW_BOTH 0
diff --git a/source/blender/makesdna/DNA_linestyle_types.h b/source/blender/makesdna/DNA_linestyle_types.h
index bac03b4efd7..262bcb5981a 100644
--- a/source/blender/makesdna/DNA_linestyle_types.h
+++ b/source/blender/makesdna/DNA_linestyle_types.h
@@ -387,6 +387,7 @@ typedef struct LineStyleThicknessModifier_Calligraphy {
#define LS_NO_SORTING (1 << 11)
#define LS_REVERSE_ORDER (1 << 12) /* for sorting */
#define LS_TEXTURE (1 << 13)
+#define LS_CHAIN_COUNT (1 << 14)
/* FreestyleLineStyle::chaining */
#define LS_CHAINING_PLAIN 1
@@ -406,6 +407,8 @@ typedef struct LineStyleThicknessModifier_Calligraphy {
/* FreestyleLineStyle::sort_key */
#define LS_SORT_KEY_DISTANCE_FROM_CAMERA 1
#define LS_SORT_KEY_2D_LENGTH 2
+#define LS_SORT_KEY_PROJECTED_X 3
+#define LS_SORT_KEY_PROJECTED_Y 4
/* FreestyleLineStyle::integration_type */
#define LS_INTEGRATION_MEAN 1
@@ -428,13 +431,14 @@ typedef struct FreestyleLineStyle {
float split_length;
float min_angle, max_angle; /* in radians, for splitting */
float min_length, max_length;
+ unsigned int chain_count;
unsigned short split_dash1, split_gap1;
unsigned short split_dash2, split_gap2;
unsigned short split_dash3, split_gap3;
int sort_key, integration_type;
float texstep;
short texact, pr_texture;
- short use_nodes, pad;
+ short use_nodes, pad[3];
unsigned short dash1, gap1, dash2, gap2, dash3, gap3;
int panel; /* for UI */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index c8b8e4d52a4..f8f962107f6 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -242,6 +242,7 @@ typedef enum ScenePassType {
SCE_PASS_SUBSURFACE_DIRECT = (1 << 28),
SCE_PASS_SUBSURFACE_INDIRECT = (1 << 29),
SCE_PASS_SUBSURFACE_COLOR = (1 << 30),
+ SCE_PASS_DEBUG = (1 << 31), /* This is a virtual pass. */
} ScenePassType;
/* note, srl->passflag is treestore element 'nr' in outliner, short still... */
@@ -835,7 +836,7 @@ typedef struct Paint {
typedef struct ImagePaintSettings {
Paint paint;
- short flag, pad;
+ short flag, missing_data;
/* for projection painting only */
short seam_bleed, normal_angle;
@@ -1733,6 +1734,11 @@ typedef enum ImagePaintMode {
#define IMAGEPAINT_PROJECT_LAYER_STENCIL 256
#define IMAGEPAINT_PROJECT_LAYER_STENCIL_INV 512
+#define IMAGEPAINT_MISSING_UVS (1 << 0)
+#define IMAGEPAINT_MISSING_MATERIAL (1 << 1)
+#define IMAGEPAINT_MISSING_TEX (1 << 2)
+#define IMAGEPAINT_MISSING_STENCIL (1 << 3)
+
/* toolsettings->uvcalc_flag */
#define UVCALC_FILLHOLES 1
#define UVCALC_NO_ASPECT_CORRECT 2 /* would call this UVCALC_ASPECT_CORRECT, except it should be default with old file */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 6f57f549efb..a267217abf6 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -57,7 +57,6 @@ struct Scopes;
struct Histogram;
struct SpaceIpo;
struct BlendHandle;
-struct RenderInfo;
struct bNodeTree;
struct uiBlock;
struct FileList;
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index ed59014cf75..382fd8c1dbd 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -534,13 +534,13 @@ typedef struct UserDef {
float fcu_inactive_alpha; /* opacity of inactive F-Curves in F-Curve Editor */
float pixelsize; /* private, set by GHOST, to multiply DPI with */
+ int virtual_pixel; /* virtual pixelsize mode */
short pie_interaction_type; /* if keeping a pie menu spawn button pressed after this time, it turns into
* a drag/release pie menu */
short pie_initial_timeout; /* direction in the pie menu will always be calculated from the initial position
* within this time limit */
int pie_animation_timeout;
- int pad2;
short pie_menu_radius; /* pie menu radius */
short pie_menu_threshold; /* pie menu distance from center before a direction is set */
@@ -854,6 +854,11 @@ typedef enum eImageDrawMethod {
IMAGE_DRAW_METHOD_DRAWPIXELS = 3,
} eImageDrawMethod;
+typedef enum eUserpref_VirtualPixel {
+ VIRTUAL_PIXEL_NATIVE = 0,
+ VIRTUAL_PIXEL_DOUBLE = 1,
+} eUserpref_VirtualPixel;
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h
index 98c12e9cc11..3efba488299 100644
--- a/source/blender/makesdna/DNA_view3d_types.h
+++ b/source/blender/makesdna/DNA_view3d_types.h
@@ -41,7 +41,6 @@ struct Base;
struct BoundBox;
struct MovieClip;
struct MovieClipUser;
-struct RenderInfo;
struct RenderEngine;
struct bGPdata;
struct SmoothView3DStore;
@@ -102,7 +101,6 @@ typedef struct RegionView3D {
struct BoundBox *clipbb;
struct RegionView3D *localvd; /* allocated backup of its self while in localview */
- struct RenderInfo *ri;
struct RenderEngine *render_engine;
struct ViewDepths *depths;
void *gpuoffscreen;
diff --git a/source/blender/makesrna/SConscript b/source/blender/makesrna/SConscript
index d0af2a522a7..4e7a564e9d4 100644
--- a/source/blender/makesrna/SConscript
+++ b/source/blender/makesrna/SConscript
@@ -118,6 +118,9 @@ if env['WITH_BF_OCEANSIM']:
if env['WITH_BF_CYCLES']:
defs.append('WITH_CYCLES')
+ if env['WITH_BF_CYCLES_DEBUG']:
+ defs.append('WITH_CYCLES_DEBUG')
+
if env['WITH_BF_SDL']:
defs.append('WITH_SDL')
@@ -127,6 +130,10 @@ if env['WITH_BF_OPENAL']:
if env['WITH_BF_JACK']:
defs.append('WITH_JACK')
+if env['WITH_BF_FREESTYLE']:
+ defs.append('WITH_FREESTYLE')
+ incs += ' ../freestyle'
+
if env['OURPLATFORM'] == 'linux':
cflags='-pthread'
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index e6bd9fb79b4..9a53ebcec03 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -155,6 +155,9 @@ set(INC_SYS
if(WITH_CYCLES)
add_definitions(-DWITH_CYCLES)
+ if(WITH_CYCLES_DEBUG)
+ add_definitions(-DWITH_CYCLES_DEBUG)
+ endif()
endif()
if(WITH_PYTHON)
@@ -265,6 +268,9 @@ if(WITH_BULLET)
endif()
if(WITH_FREESTYLE)
+ list(APPEND INC
+ ../../freestyle
+ )
add_definitions(-DWITH_FREESTYLE)
endif()
diff --git a/source/blender/makesrna/intern/SConscript b/source/blender/makesrna/intern/SConscript
index 4e643fb302f..d1eab5ca9db 100644
--- a/source/blender/makesrna/intern/SConscript
+++ b/source/blender/makesrna/intern/SConscript
@@ -142,9 +142,12 @@ if env['WITH_BF_COLLADA']:
if env['WITH_BF_CYCLES']:
defs.append('WITH_CYCLES')
+ if env['WITH_BF_CYCLES_DEBUG']:
+ defs.append('WITH_CYCLES_DEBUG')
if env['WITH_BF_FREESTYLE']:
defs.append('WITH_FREESTYLE')
+ incs += ' ../../freestyle'
if env['OURPLATFORM'] == 'linux':
cflags='-pthread'
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 83fe56102ac..51d81295f8c 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -60,11 +60,14 @@ EnumPropertyItem id_type_items[] = {
{ID_LI, "LIBRARY", ICON_LIBRARY_DATA_DIRECT, "Library", ""},
{ID_LS, "LINESTYLE", ICON_LINE_DATA, "Line Style", ""},
{ID_LT, "LATTICE", ICON_LATTICE_DATA, "Lattice", ""},
+ {ID_MSK, "MASK", ICON_MOD_MASK, "Mask", ""},
{ID_MA, "MATERIAL", ICON_MATERIAL_DATA, "Material", ""},
{ID_MB, "META", ICON_META_DATA, "MetaBall", ""},
{ID_ME, "MESH", ICON_MESH_DATA, "Mesh", ""},
{ID_NT, "NODETREE", ICON_NODETREE, "NodeTree", ""},
{ID_OB, "OBJECT", ICON_OBJECT_DATA, "Object", ""},
+ {ID_PC, "PAINTCURVE", ICON_CURVE_BEZCURVE, "Paint Curve", ""},
+ {ID_PAL, "PALETTE", ICON_COLOR, "Palette", ""},
{ID_PA, "PARTICLE", ICON_PARTICLE_DATA, "Particle", ""},
{ID_SCE, "SCENE", ICON_SCENE_DATA, "Scene", ""},
{ID_SCR, "SCREEN", ICON_SPLITSCREEN, "Screen", ""},
diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c
index 1ff99271146..bbc2e0572fa 100644
--- a/source/blender/makesrna/intern/rna_brush.c
+++ b/source/blender/makesrna/intern/rna_brush.c
@@ -264,7 +264,7 @@ static int rna_BrushCapabilities_has_spacing_get(PointerRNA *ptr)
return (!(br->flag & BRUSH_ANCHORED));
}
-static int rna_SculptToolCapabilities_has_strength_get(PointerRNA *ptr)
+static int rna_SculptToolCapabilities_has_strength_pressure_get(PointerRNA *ptr)
{
Brush *br = (Brush *)ptr->data;
return !ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK);
@@ -689,7 +689,7 @@ static void rna_def_sculpt_capabilities(BlenderRNA *brna)
SCULPT_TOOL_CAPABILITY(has_secondary_color, "Has Secondary Color");
SCULPT_TOOL_CAPABILITY(has_smooth_stroke, "Has Smooth Stroke");
SCULPT_TOOL_CAPABILITY(has_space_attenuation, "Has Space Attenuation");
- SCULPT_TOOL_CAPABILITY(has_strength, "Has Strength");
+ SCULPT_TOOL_CAPABILITY(has_strength_pressure, "Has Strength Pressure");
SCULPT_TOOL_CAPABILITY(has_gravity, "Has Gravity");
#undef SCULPT_CAPABILITY
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index 0b129bab524..90c9cd108cd 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -589,6 +589,13 @@ static void rna_def_image(BlenderRNA *brna)
RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ prop = RNA_def_property(srna, "generated_color", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_float_sdna(prop, NULL, "gen_color");
+ RNA_def_property_array(prop, 4);
+ RNA_def_property_ui_text(prop, "Color", "Fill color for the generated image");
+ RNA_def_property_update(prop, NC_IMAGE | ND_DISPLAY, "rna_Image_generated_update");
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+
/* realtime properties */
prop = RNA_def_property(srna, "mapping", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c
index 1fb46c009a0..d9a59c4dc55 100644
--- a/source/blender/makesrna/intern/rna_image_api.c
+++ b/source/blender/makesrna/intern/rna_image_api.c
@@ -115,7 +115,7 @@ static void rna_Image_save(Image *image, bContext *C, ReportList *reports)
if (ibuf) {
char filename[FILE_MAX];
BLI_strncpy(filename, image->name, sizeof(filename));
- BLI_path_abs(filename, G.main->name);
+ BLI_path_abs(filename, ID_BLEND_PATH(G.main, &image->id));
if (image->packedfile) {
if (writePackedFile(reports, image->name, image->packedfile, 0) != RET_OK) {
diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c
index 96b81f12620..2259db1de66 100644
--- a/source/blender/makesrna/intern/rna_linestyle.c
+++ b/source/blender/makesrna/intern/rna_linestyle.c
@@ -1322,6 +1322,8 @@ static void rna_def_linestyle(BlenderRNA *brna)
static EnumPropertyItem sort_key_items[] = {
{LS_SORT_KEY_DISTANCE_FROM_CAMERA, "DISTANCE_FROM_CAMERA", 0, "Distance from Camera", "Sort by distance from camera (closer lines lie on top of further lines)"},
{LS_SORT_KEY_2D_LENGTH, "2D_LENGTH", 0, "2D Length", "Sort by curvilinear 2D length (longer lines lie on top of shorter lines)"},
+ {LS_SORT_KEY_PROJECTED_X, "PROJECTED_X", 0, "Projected X", "Sort by the projected X value in the image coordinate system"},
+ {LS_SORT_KEY_PROJECTED_Y, "PROJECTED_Y", 0, "Projected Y", "Sort by the projected Y value in the image coordinate system"},
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem sort_order_items[] = {
@@ -1488,6 +1490,16 @@ static void rna_def_linestyle(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Max 2D Length", "Maximum curvilinear 2D length for the selection of chains");
RNA_def_property_update(prop, NC_LINESTYLE, "rna_LineStyle_update");
+ prop = RNA_def_property(srna, "use_chain_count", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LS_CHAIN_COUNT);
+ RNA_def_property_ui_text(prop, "Use Chain Count", "Enable the selection of first N chains");
+ RNA_def_property_update(prop, NC_LINESTYLE, "rna_LineStyle_update");
+
+ prop = RNA_def_property(srna, "chain_count", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_int_sdna(prop, NULL, "chain_count");
+ RNA_def_property_ui_text(prop, "Chain Count", "Chain count for the selection of first N chains");
+ RNA_def_property_update(prop, NC_LINESTYLE, "rna_LineStyle_update");
+
prop = RNA_def_property(srna, "use_split_pattern", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", LS_SPLIT_PATTERN);
RNA_def_property_ui_text(prop, "Use Split Pattern", "Enable chain splitting by dashed line patterns");
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index 1ef39ec4a77..2e4f24fc0ce 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -204,7 +204,9 @@ static void rna_Material_active_paint_texture_index_update(Main *bmain, Scene *s
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
- ED_space_image_set(sima, scene, scene->obedit, image);
+
+ if (!sima->pin)
+ ED_space_image_set(sima, scene, scene->obedit, image);
}
}
}
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 699bfaa0f93..690468a5278 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -2624,7 +2624,7 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "dupfacesca");
RNA_def_property_range(prop, 0.001f, 10000.0f);
RNA_def_property_ui_text(prop, "Dupli Faces Scale", "Scale the DupliFace objects");
- RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, NULL);
+ RNA_def_property_update(prop, NC_OBJECT | ND_DRAW, "rna_Object_internal_update");
prop = RNA_def_property(srna, "dupli_group", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "dup_group");
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 284377d34f9..0ee654d4ecc 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -71,6 +71,9 @@ EnumPropertyItem render_pass_type_items[] = {
{SCE_PASS_SUBSURFACE_DIRECT, "SUBSURFACE_DIRECT", 0, "Subsurface Direct", ""},
{SCE_PASS_SUBSURFACE_INDIRECT, "SUBSURFACE_INDIRECT", 0, "Subsurface Indirect", ""},
{SCE_PASS_SUBSURFACE_COLOR, "SUBSURFACE_COLOR", 0, "Subsurface Color", ""},
+#ifdef WITH_CYCLES_DEBUG
+ {SCE_PASS_DEBUG, "DEBUG", 0, "Pass used for render engine debugging", ""},
+#endif
{0, NULL, 0, NULL, NULL}
};
@@ -584,6 +587,10 @@ static void rna_def_render_engine(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_PREVIEW);
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+ prop = RNA_def_property(srna, "bl_use_texture_preview", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "type->flag", RE_USE_TEXTURE_PREVIEW);
+ RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
+
prop = RNA_def_property(srna, "bl_use_postprocess", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "type->flag", RE_USE_POSTPROCESS);
RNA_def_property_flag(prop, PROP_REGISTER_OPTIONAL);
@@ -683,6 +690,11 @@ static void rna_def_render_pass(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
+ static EnumPropertyItem render_pass_debug_type_items[] = {
+ {RENDER_PASS_DEBUG_BVH_TRAVERSAL_STEPS, "BVH_TRAVERSAL_STEPS", 0, "BVH Traversal Steps", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "RenderPass", NULL);
RNA_def_struct_ui_text(srna, "Render Pass", "");
@@ -712,6 +724,11 @@ static void rna_def_render_pass(BlenderRNA *brna)
RNA_def_property_dynamic_array_funcs(prop, "rna_RenderPass_rect_get_length");
RNA_def_property_float_funcs(prop, "rna_RenderPass_rect_get", "rna_RenderPass_rect_set", NULL);
+ prop = RNA_def_property(srna, "debug_type", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "debug_type");
+ RNA_def_property_enum_items(prop, render_pass_debug_type_items);
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
RNA_define_verify_sdna(1);
}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 682a7f4ee31..70ce87ab68b 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -370,6 +370,10 @@ EnumPropertyItem bake_save_mode_items[] = {
#include "RE_engine.h"
+#ifdef WITH_FREESTYLE
+#include "FRS_freestyle.h"
+#endif
+
static void rna_SpaceImageEditor_uv_sculpt_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
{
ED_space_image_uv_sculpt_update(bmain->wm.first, scene->toolsettings);
@@ -1179,6 +1183,13 @@ static void rna_Scene_freestyle_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
DAG_id_tag_update(&scene->id, 0);
}
+static void rna_Scene_use_view_map_cache_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
+{
+#ifdef WITH_FREESTYLE
+ FRS_free_view_map_cache();
+#endif
+}
+
static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value)
{
Scene *scene = (Scene *)ptr->id.data;
@@ -3109,6 +3120,11 @@ static void rna_def_freestyle_settings(BlenderRNA *brna)
"Enable advanced edge detection options (sphere radius and Kr derivative epsilon)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_freestyle_update");
+ prop = RNA_def_property(srna, "use_view_map_cache", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flags", FREESTYLE_VIEW_MAP_CACHE);
+ RNA_def_property_ui_text(prop, "View Map Cache", "Keep the computed view map and avoid re-calculating it if mesh geometry is unchanged");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_use_view_map_cache_update");
+
prop = RNA_def_property(srna, "sphere_radius", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sphere_radius");
RNA_def_property_range(prop, 0.0, 1000.0);
@@ -4547,7 +4563,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_enum_sdna(prop, NULL, "alphamode");
RNA_def_property_enum_items(prop, alpha_mode_items);
RNA_def_property_ui_text(prop, "Alpha Mode", "Representation of alpha information in the RGBA pixels");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "octree_resolution", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "ocres");
@@ -4609,45 +4625,45 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_shadows", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SHADOW);
RNA_def_property_ui_text(prop, "Shadows", "Calculate shadows while rendering");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "use_envmaps", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_ENVMAP);
RNA_def_property_ui_text(prop, "Environment Maps", "Calculate environment maps while rendering");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "use_sss", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_SSS);
RNA_def_property_ui_text(prop, "Subsurface Scattering", "Calculate sub-surface scattering in materials rendering");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "use_raytrace", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_RAYTRACE);
RNA_def_property_ui_text(prop, "Raytracing",
"Pre-calculate the raytrace accelerator and render raytracing effects");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "use_textures", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "scemode", R_NO_TEX);
RNA_def_property_ui_text(prop, "Textures", "Use textures to affect material properties");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "use_edge_enhance", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_EDGE);
RNA_def_property_ui_text(prop, "Edge", "Create a toon outline around the edges of geometry");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "edge_threshold", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "edgeint");
RNA_def_property_range(prop, 0, 255);
RNA_def_property_ui_text(prop, "Edge Threshold", "Threshold for drawing outlines on geometry edges");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "edge_color", PROP_FLOAT, PROP_COLOR);
RNA_def_property_float_sdna(prop, NULL, "edgeR");
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Edge Color", "Edge color");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "use_freestyle", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "mode", R_EDGE_FRS);
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index d48d8589f96..09e42e48e93 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -308,12 +308,22 @@ static void rna_ImaPaint_mode_update(Main *UNUSED(bmain), Scene *scene, PointerR
BKE_texpaint_slots_refresh_object(scene, ob);
/* we assume that changing the current mode will invalidate the uv layers so we need to refresh display */
- GPU_drawobject_free(ob->derivedFinal);
- WM_main_add_notifier(NC_GEOM | ND_DATA, &ob->id);
+ GPU_drawobject_free(ob->derivedFinal);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
+}
+
+static void rna_ImaPaint_stencil_update(Main *UNUSED(bmain), Scene *scene, PointerRNA *UNUSED(ptr))
+{
+ Object *ob = OBACT;
+ GPU_drawobject_free(ob->derivedFinal);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
+ WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
}
static void rna_ImaPaint_canvas_update(Main *bmain, Scene *scene, PointerRNA *UNUSED(ptr))
{
+ Object *ob = OBACT;
bScreen *sc;
Image *ima = scene->toolsettings->imapaint.canvas;
@@ -324,14 +334,23 @@ static void rna_ImaPaint_canvas_update(Main *bmain, Scene *scene, PointerRNA *UN
for (sl = sa->spacedata.first; sl; sl = sl->next) {
if (sl->spacetype == SPACE_IMAGE) {
SpaceImage *sima = (SpaceImage *)sl;
- ED_space_image_set(sima, scene, scene->obedit, ima);
+
+ if (!sima->pin)
+ ED_space_image_set(sima, scene, scene->obedit, ima);
}
}
}
}
-
+
+ GPU_drawobject_free(ob->derivedFinal);
+ BKE_paint_proj_mesh_data_check(scene, ob, NULL, NULL, NULL, NULL);
WM_main_add_notifier(NC_OBJECT | ND_DRAW, NULL);
}
+
+static int rna_ImaPaint_detect_data(ImagePaintSettings *imapaint)
+{
+ return imapaint->missing_data == 0;
+}
#else
static void rna_def_palettecolor(BlenderRNA *brna)
@@ -612,6 +631,7 @@ static void rna_def_image_paint(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
static EnumPropertyItem paint_type_items[] = {
{IMAGEPAINT_MODE_MATERIAL, "MATERIAL", 0,
@@ -625,6 +645,13 @@ static void rna_def_image_paint(BlenderRNA *brna)
RNA_def_struct_sdna(srna, "ImagePaintSettings");
RNA_def_struct_path_func(srna, "rna_ImagePaintSettings_path");
RNA_def_struct_ui_text(srna, "Image Paint", "Properties of image and texture painting mode");
+
+ /* functions */
+ func = RNA_def_function(srna, "detect_data", "rna_ImaPaint_detect_data");
+ RNA_def_function_ui_description(func, "Check if required texpaint data exist");
+
+ /* return type */
+ RNA_def_function_return(func, RNA_def_boolean(func, "ok", 1, "", ""));
/* booleans */
prop = RNA_def_property(srna, "use_occlude", PROP_BOOLEAN, PROP_NONE);
@@ -656,7 +683,7 @@ static void rna_def_image_paint(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "stencil");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Stencil Image", "Image used as stencil");
- RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_viewport_update");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_stencil_update");
prop = RNA_def_property(srna, "canvas", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
@@ -698,7 +725,32 @@ static void rna_def_image_paint(BlenderRNA *brna)
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, paint_type_items);
RNA_def_property_ui_text(prop, "Mode", "Mode of operation for projection painting");
- RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_mode_update");
+ RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, "rna_ImaPaint_mode_update");
+
+ /* Missing data */
+ prop = RNA_def_property(srna, "missing_uvs", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_UVS);
+ RNA_def_property_ui_text(prop, "Missing UVs",
+ "A UV layer is missing on the mesh");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "missing_materials", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_MATERIAL);
+ RNA_def_property_ui_text(prop, "Missing Materials",
+ "The mesh is missing materials");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "missing_stencil", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_STENCIL);
+ RNA_def_property_ui_text(prop, "Missing Stencil",
+ "Image Painting does not have a stencil");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+
+ prop = RNA_def_property(srna, "missing_texture", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "missing_data", IMAGEPAINT_MISSING_TEX);
+ RNA_def_property_ui_text(prop, "Missing Texture",
+ "Image Painting does not have a texture to paint on");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
}
static void rna_def_particle_edit(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c
index 887670eb5ff..55262a98b2e 100644
--- a/source/blender/makesrna/intern/rna_smoke.c
+++ b/source/blender/makesrna/intern/rna_smoke.c
@@ -311,7 +311,7 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "resolution_max", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "maxres");
- RNA_def_property_range(prop, 24, 512);
+ RNA_def_property_range(prop, 6, 512);
RNA_def_property_ui_range(prop, 24, 512, 2, -1);
RNA_def_property_ui_text(prop, "Max Res", "Maximal resolution used in the fluid domain");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index aa378955fb0..7fdc9ba1e79 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -120,6 +120,16 @@ static void rna_userdef_dpi_update(Main *UNUSED(bmain), Scene *UNUSED(scene), Po
WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); /* refresh region sizes */
}
+static void rna_userdef_virtual_pixel_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
+{
+ /* font's are stored at each DPI level, without this we can easy load 100's of fonts */
+ BLF_cache_clear();
+
+ BKE_userdef_state();
+ WM_main_add_notifier(NC_WINDOW, NULL); /* full redraw */
+ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); /* refresh region sizes */
+}
+
static void rna_userdef_language_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *UNUSED(ptr))
{
BLF_cache_clear();
@@ -3743,6 +3753,12 @@ static void rna_def_userdef_system(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem virtual_pixel_mode_items[] = {
+ {VIRTUAL_PIXEL_NATIVE, "NATIVE", 0, "Native", "Use native pixel size of the display"},
+ {VIRTUAL_PIXEL_DOUBLE, "DOUBLE", 0, "Double", "Use double the native pixel size of the display"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "UserPreferencesSystem", NULL);
RNA_def_struct_sdna(srna, "UserDef");
RNA_def_struct_nested(brna, srna, "UserPreferences");
@@ -3762,6 +3778,12 @@ static void rna_def_userdef_system(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display");
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
+ prop = RNA_def_property(srna, "virtual_pixel_mode", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "virtual_pixel");
+ RNA_def_property_enum_items(prop, virtual_pixel_mode_items);
+ RNA_def_property_ui_text(prop, "Virtual Pixel Mode", "Modify the pixel size for hi-res devices");
+ RNA_def_property_update(prop, 0, "rna_userdef_virtual_pixel_update");
+
prop = RNA_def_property(srna, "font_path_ui", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "font_path_ui");
RNA_def_property_ui_text(prop, "Interface Font", "Path to interface font");
diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt
index 584df9eee75..06e9f8f5b67 100644
--- a/source/blender/modifiers/CMakeLists.txt
+++ b/source/blender/modifiers/CMakeLists.txt
@@ -132,6 +132,10 @@ if(WITH_MOD_OCEANSIM)
add_definitions(-DWITH_OCEANSIM)
endif()
+if(WITH_BULLET)
+ add_definitions(-DWITH_BULLET)
+endif()
+
if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
diff --git a/source/blender/modifiers/SConscript b/source/blender/modifiers/SConscript
index 88bf33db38e..c15a562abc0 100644
--- a/source/blender/modifiers/SConscript
+++ b/source/blender/modifiers/SConscript
@@ -63,6 +63,9 @@ if env['WITH_BF_FLUID']:
if env['WITH_BF_OCEANSIM']:
defs.append('WITH_OCEANSIM')
+if env['WITH_BF_BULLET']:
+ defs.append('WITH_BULLET')
+
if env['WITH_BF_GAMEENGINE']:
incs.append('#/extern/recastnavigation')
defs.append('WITH_GAMEENGINE')
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 2768d9412d7..40db49afef2 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -404,6 +404,12 @@ static DerivedMesh *arrayModifier_doArray(
int *full_doubles_map = NULL;
int tot_doubles;
+ const bool use_merge = amd->flags & MOD_ARR_MERGE;
+ const bool use_recalc_normals = (dm->dirty & DM_DIRTY_NORMALS) || use_merge;
+ const bool use_offset_ob = ((amd->offset_type & MOD_ARR_OFF_OBJ) && amd->offset_ob);
+ /* allow pole vertices to be used by many faces */
+ const bool with_follow = use_offset_ob;
+
int start_cap_nverts = 0, start_cap_nedges = 0, start_cap_npolys = 0, start_cap_nloops = 0;
int end_cap_nverts = 0, end_cap_nedges = 0, end_cap_npolys = 0, end_cap_nloops = 0;
int result_nverts = 0, result_nedges = 0, result_npolys = 0, result_nloops = 0;
@@ -451,7 +457,7 @@ static DerivedMesh *arrayModifier_doArray(
offset[3][j] += amd->scale[j] * vertarray_size(src_mvert, chunk_nverts, j);
}
- if ((amd->offset_type & MOD_ARR_OFF_OBJ) && (amd->offset_ob)) {
+ if (use_offset_ob) {
float obinv[4][4];
float result_mat[4][4];
@@ -514,7 +520,7 @@ static DerivedMesh *arrayModifier_doArray(
result = CDDM_from_template(dm, result_nverts, result_nedges, 0, result_nloops, result_npolys);
result_dm_verts = CDDM_get_verts(result);
- if (amd->flags & MOD_ARR_MERGE) {
+ if (use_merge) {
/* Will need full_doubles_map for handling merge */
full_doubles_map = MEM_mallocN(sizeof(int) * result_nverts, "mod array doubles map");
fill_vn_i(full_doubles_map, result_nverts, -1);
@@ -561,6 +567,15 @@ static DerivedMesh *arrayModifier_doArray(
/* apply offset to all new verts */
for (i = 0; i < chunk_nverts; i++, mv++, mv_prev++) {
mul_m4_v3(current_offset, mv->co);
+
+ /* We have to correct normals too, if we do not tag them as dirty! */
+ if (!use_recalc_normals) {
+ float no[3];
+ normal_short_to_float_v3(no, mv->no);
+ mul_mat3_m4_v3(current_offset, no);
+ normalize_v3(no);
+ normal_float_to_short_v3(mv->no, no);
+ }
}
/* adjust edge vertex indices */
@@ -583,7 +598,7 @@ static DerivedMesh *arrayModifier_doArray(
}
/* Handle merge between chunk n and n-1 */
- if ((amd->flags & MOD_ARR_MERGE) && (c >= 1)) {
+ if (use_merge && (c >= 1)) {
if (!offset_has_scale && (c >= 2)) {
/* Mapping chunk 3 to chunk 2 is a translation of mapping 2 to 1
* ... that is except if scaling makes the distance grow */
@@ -594,10 +609,15 @@ static DerivedMesh *arrayModifier_doArray(
int target = full_doubles_map[prev_chunk_index];
if (target != -1) {
target += chunk_nverts; /* translate mapping */
- /* The rule here is to not follow mapping to chunk N-2, which could be too far
- * so if target vertex was itself mapped, then this vertex is not mapped */
if (full_doubles_map[target] != -1) {
- target = -1;
+ if (with_follow) {
+ target = full_doubles_map[target];
+ }
+ else {
+ /* The rule here is to not follow mapping to chunk N-2, which could be too far
+ * so if target vertex was itself mapped, then this vertex is not mapped */
+ target = -1;
+ }
}
}
full_doubles_map[this_chunk_index] = target;
@@ -612,7 +632,7 @@ static DerivedMesh *arrayModifier_doArray(
c * chunk_nverts,
chunk_nverts,
amd->merge_dist,
- false);
+ with_follow);
}
}
}
@@ -622,10 +642,7 @@ static DerivedMesh *arrayModifier_doArray(
copy_m4_m4(final_offset, current_offset);
- if ((amd->flags & MOD_ARR_MERGE) &&
- (amd->flags & MOD_ARR_MERGEFINAL) &&
- (count > 1))
- {
+ if (use_merge && (amd->flags & MOD_ARR_MERGEFINAL) && (count > 1)) {
/* Merge first and last copies */
dm_mvert_map_doubles(
full_doubles_map,
@@ -635,7 +652,7 @@ static DerivedMesh *arrayModifier_doArray(
first_chunk_start,
first_chunk_nverts,
amd->merge_dist,
- false);
+ with_follow);
}
/* start capping */
@@ -651,7 +668,7 @@ static DerivedMesh *arrayModifier_doArray(
result_npolys - start_cap_npolys - end_cap_npolys,
start_cap_nverts, start_cap_nedges, start_cap_nloops, start_cap_npolys);
/* Identify doubles with first chunk */
- if (amd->flags & MOD_ARR_MERGE) {
+ if (use_merge) {
dm_mvert_map_doubles(
full_doubles_map,
result_dm_verts,
@@ -676,7 +693,7 @@ static DerivedMesh *arrayModifier_doArray(
result_npolys - end_cap_npolys,
end_cap_nverts, end_cap_nedges, end_cap_nloops, end_cap_npolys);
/* Identify doubles with last chunk */
- if (amd->flags & MOD_ARR_MERGE) {
+ if (use_merge) {
dm_mvert_map_doubles(
full_doubles_map,
result_dm_verts,
@@ -690,19 +707,17 @@ static DerivedMesh *arrayModifier_doArray(
}
/* done capping */
- /* In case org dm has dirty normals, or we made some merging, mark normals as dirty in new dm!
- * TODO: we may need to set other dirty flags as well?
- */
- if ((dm->dirty & DM_DIRTY_NORMALS) || full_doubles_map) {
- result->dirty |= DM_DIRTY_NORMALS;
- }
-
/* Handle merging */
tot_doubles = 0;
- if (full_doubles_map) {
+ if (use_merge) {
for (i = 0; i < result_nverts; i++) {
if (full_doubles_map[i] != -1) {
- tot_doubles++;
+ if (i == full_doubles_map[i]) {
+ full_doubles_map[i] = -1;
+ }
+ else {
+ tot_doubles++;
+ }
}
}
if (tot_doubles > 0) {
@@ -710,6 +725,14 @@ static DerivedMesh *arrayModifier_doArray(
}
MEM_freeN(full_doubles_map);
}
+
+ /* In case org dm has dirty normals, or we made some merging, mark normals as dirty in new dm!
+ * TODO: we may need to set other dirty flags as well?
+ */
+ if (use_recalc_normals) {
+ result->dirty |= DM_DIRTY_NORMALS;
+ }
+
return result;
}
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 825015fa25c..1e422806d80 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -218,6 +218,7 @@ static bool skin_frame_find_contained_faces(const Frame *frame,
/* Returns true if hull is successfully built, false otherwise */
static bool build_hull(SkinOutput *so, Frame **frames, int totframe)
{
+#ifdef WITH_BULLET
BMesh *bm = so->bm;
BMOperator op;
BMIter iter;
@@ -326,6 +327,11 @@ static bool build_hull(SkinOutput *so, Frame **frames, int totframe)
BM_mesh_delete_hflag_tagged(bm, BM_ELEM_TAG, BM_EDGE | BM_FACE);
return true;
+#else
+ (void)so, (void)frames, (void)totframe;
+ (void)skin_frame_find_contained_faces;
+ return false;
+#endif
}
/* Returns the average frame side length (frames are rectangular, so
diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c
index 76986583ef5..7349ca9f9ef 100644
--- a/source/blender/modifiers/intern/MOD_wireframe.c
+++ b/source/blender/modifiers/intern/MOD_wireframe.c
@@ -60,7 +60,7 @@ static void copyData(ModifierData *md, ModifierData *target)
static bool isDisabled(ModifierData *UNUSED(md), int UNUSED(useRenderParams))
{
- return 0;
+ return false;
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
@@ -75,6 +75,11 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
}
+static bool dependsOnNormals(ModifierData *UNUSED(md))
+{
+ return true;
+}
+
static DerivedMesh *WireframeModifier_do( WireframeModifierData *wmd, Object *ob, DerivedMesh *dm)
{
DerivedMesh *result;
@@ -135,7 +140,7 @@ ModifierTypeInfo modifierType_Wireframe = {
/* isDisabled */ isDisabled,
/* updateDepgraph */ NULL,
/* dependsOnTime */ NULL,
- /* dependsOnNormals */ NULL,
+ /* dependsOnNormals */ dependsOnNormals,
/* foreachObjectLink */ NULL,
/* foreachIDLink */ NULL,
/* foreachTexLink */ NULL,
diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c
index 0893d2022a0..2347564c696 100644
--- a/source/blender/nodes/intern/node_exec.c
+++ b/source/blender/nodes/intern/node_exec.c
@@ -160,7 +160,6 @@ bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, bNodeTree *ntree, bNo
bNode **nodelist;
int totnodes, n;
/* XXX texnodes have threading issues with muting, have to disable it there ... */
- bool use_muting = (ntree->type != NTREE_TEXTURE);
/* ensure all sock->link pointers and node levels are correct */
ntreeUpdateTree(G.main, ntree);
@@ -184,7 +183,7 @@ bNodeTreeExec *ntree_exec_begin(bNodeExecContext *context, bNodeTree *ntree, bNo
for (sock = node->inputs.first; sock; sock = sock->next)
node_init_input_index(sock, &index);
- if (use_muting && (node->flag & NODE_MUTED || node->type == NODE_REROUTE)) {
+ if (node->flag & NODE_MUTED || node->type == NODE_REROUTE) {
for (sock = node->outputs.first; sock; sock = sock->next)
node_init_output_index(sock, &index, &node->internal_links);
}
@@ -306,7 +305,7 @@ bool ntreeExecThreadNodes(bNodeTreeExec *exec, bNodeThreadStack *nts, void *call
*/
// if (node->typeinfo->compatibility == NODE_NEW_SHADING)
// return false;
- if (node->typeinfo->execfunc)
+ if (node->typeinfo->execfunc && !(node->flag & NODE_MUTED))
node->typeinfo->execfunc(callerdata, thread, node, &nodeexec->data, nsin, nsout);
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_camera.c b/source/blender/nodes/shader/nodes/node_shader_camera.c
index 231af7e7d37..49ebb15d7a4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_camera.c
+++ b/source/blender/nodes/shader/nodes/node_shader_camera.c
@@ -47,7 +47,7 @@ static void node_shader_exec_camera(void *data, int UNUSED(thread), bNode *UNUSE
ShadeInput *shi = ((ShaderCallData *)data)->shi; /* Data we need for shading. */
copy_v3_v3(out[0]->vec, shi->co); /* get view vector */
- out[1]->vec[0] = fabs(shi->co[2]); /* get view z-depth */
+ out[1]->vec[0] = fabsf(shi->co[2]); /* get view z-depth */
out[2]->vec[0] = normalize_v3(out[0]->vec); /* get view distance */
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c
index d5ba8231cce..dc5971909d2 100644
--- a/source/blender/nodes/shader/nodes/node_shader_math.c
+++ b/source/blender/nodes/shader/nodes/node_shader_math.c
@@ -74,25 +74,25 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
case 4: /* Sine */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- r = sin(a);
+ r = sinf(a);
else
- r = sin(b);
+ r = sinf(b);
break;
}
case 5: /* Cosine */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- r = cos(a);
+ r = cosf(a);
else
- r = cos(b);
+ r = cosf(b);
break;
}
case 6: /* Tangent */
{
if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */
- r = tan(a);
+ r = tanf(a);
else
- r = tan(b);
+ r = tanf(b);
break;
}
case 7: /* Arc-Sine */
@@ -100,14 +100,14 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
/* Can't do the impossible... */
if (a <= 1 && a >= -1)
- r = asin(a);
+ r = asinf(a);
else
r = 0.0;
}
else {
/* Can't do the impossible... */
if (b <= 1 && b >= -1)
- r = asin(b);
+ r = asinf(b);
else
r = 0.0;
}
@@ -118,14 +118,14 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */
/* Can't do the impossible... */
if (a <= 1 && a >= -1)
- r = acos(a);
+ r = acosf(a);
else
r = 0.0;
}
else {
/* Can't do the impossible... */
if (b <= 1 && b >= -1)
- r = acos(b);
+ r = acosf(b);
else
r = 0.0;
}
@@ -218,7 +218,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode
}
case 18: /* Absolute */
{
- r = fabs(a);
+ r = fabsf(a);
break;
}
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_vectMath.c b/source/blender/nodes/shader/nodes/node_shader_vectMath.c
index b40bf6bc71a..f2ea2faa5a7 100644
--- a/source/blender/nodes/shader/nodes/node_shader_vectMath.c
+++ b/source/blender/nodes/shader/nodes/node_shader_vectMath.c
@@ -59,14 +59,14 @@ static void node_shader_exec_vect_math(void *UNUSED(data), int UNUSED(thread), b
out[0]->vec[1] = vec1[1] + vec2[1];
out[0]->vec[2] = vec1[2] + vec2[2];
- out[1]->vec[0] = (fabs(out[0]->vec[0]) + fabs(out[0]->vec[0]) + fabs(out[0]->vec[0])) / 3;
+ out[1]->vec[0] = (fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[0])) / 3;
}
else if (node->custom1 == 1) { /* Subtract */
out[0]->vec[0] = vec1[0] - vec2[0];
out[0]->vec[1] = vec1[1] - vec2[1];
out[0]->vec[2] = vec1[2] - vec2[2];
- out[1]->vec[0] = (fabs(out[0]->vec[0]) + fabs(out[0]->vec[0]) + fabs(out[0]->vec[0])) / 3;
+ out[1]->vec[0] = (fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[0]) + fabsf(out[0]->vec[0])) / 3;
}
else if (node->custom1 == 2) { /* Average */
out[0]->vec[0] = vec1[0] + vec2[0];
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 02f15705ad1..1b790f87faf 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -140,7 +140,7 @@ static void foreach_nodeclass(Scene *UNUSED(scene), void *calldata, bNodeClassCa
/* XXX muting disabled in previews because of threading issues with the main execution
* it works here, but disabled for consistency
*/
-#if 0
+#if 1
static void localize(bNodeTree *localtree, bNodeTree *UNUSED(ntree))
{
bNode *node, *node_next;
diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c
index e01b7ec49f1..42c684b8247 100644
--- a/source/blender/nodes/texture/node_texture_util.c
+++ b/source/blender/nodes/texture/node_texture_util.c
@@ -140,11 +140,19 @@ void tex_do_preview(bNodePreview *preview, const float coord[2], const float col
void tex_output(bNode *node, bNodeExecData *execdata, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *cdata)
{
TexDelegate *dg;
- if (!out->data)
- /* Freed in tex_end_exec (node.c) */
- dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
- else
- dg = out->data;
+
+ if (node->flag & NODE_MUTED) {
+ /* do not add a delegate if the node is muted */
+ return;
+ }
+ else {
+ if (!out->data)
+ /* Freed in tex_end_exec (node.c) */
+ dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate");
+ else
+ dg = out->data;
+ }
+
dg->cdata = cdata;
dg->fn = texfn;
diff --git a/source/blender/nodes/texture/nodes/node_texture_math.c b/source/blender/nodes/texture/nodes/node_texture_math.c
index 9bd2532b4b8..94e778e10fb 100644
--- a/source/blender/nodes/texture/nodes/node_texture_math.c
+++ b/source/blender/nodes/texture/nodes/node_texture_math.c
@@ -72,24 +72,24 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
}
case 4: /* Sine */
{
- *out = sin(in0);
+ *out = sinf(in0);
break;
}
case 5: /* Cosine */
{
- *out = cos(in0);
+ *out = cosf(in0);
break;
}
case 6: /* Tangent */
{
- *out = tan(in0);
+ *out = tanf(in0);
break;
}
case 7: /* Arc-Sine */
{
/* Can't do the impossible... */
if (in0 <= 1 && in0 >= -1)
- *out = asin(in0);
+ *out = asinf(in0);
else
*out = 0.0;
break;
@@ -98,7 +98,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
{
/* Can't do the impossible... */
if (in0 <= 1 && in0 >= -1)
- *out = acos(in0);
+ *out = acosf(in0);
else
*out = 0.0;
break;
@@ -185,7 +185,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor
case 18: /* Absolute */
{
- *out = fabs(in0);
+ *out = fabsf(in0);
break;
}
diff --git a/source/blender/python/bmesh/bmesh_py_ops_call.c b/source/blender/python/bmesh/bmesh_py_ops_call.c
index 9c9b69186ab..2c07df98973 100644
--- a/source/blender/python/bmesh/bmesh_py_ops_call.c
+++ b/source/blender/python/bmesh/bmesh_py_ops_call.c
@@ -507,7 +507,7 @@ static int bpy_slot_from_py(BMesh *bm, BMOperator *bmop, BMOpSlot *slot, PyObjec
return -1;
}
}
- /* fall-through */
+ break;
}
default:
/* TODO --- many others */
diff --git a/source/blender/python/intern/bpy_app_translations.c b/source/blender/python/intern/bpy_app_translations.c
index 109e5606037..0114e8e65e4 100644
--- a/source/blender/python/intern/bpy_app_translations.c
+++ b/source/blender/python/intern/bpy_app_translations.c
@@ -86,16 +86,15 @@ static unsigned int _ghashutil_keyhash(const void *ptr)
return hash ^ BLI_ghashutil_strhash(key->msgid);
}
-static int _ghashutil_keycmp(const void *a, const void *b)
+static bool _ghashutil_keycmp(const void *a, const void *b)
{
const GHashKey *A = a;
const GHashKey *B = b;
/* Note: comparing msgid first, most of the time it will be enough! */
- int cmp = BLI_ghashutil_strcmp(A->msgid, B->msgid);
- if (cmp == 0)
+ if (BLI_ghashutil_strcmp(A->msgid, B->msgid) == false)
return BLI_ghashutil_strcmp(A->msgctxt, B->msgctxt);
- return cmp;
+ return true; /* true means they are not equal! */
}
static void _ghashutil_keyfree(void *ptr)
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index ddfbfecc46e..d46c95a25b8 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -420,7 +420,7 @@ static void python_script_error_jump_text(struct Text *text)
typedef struct {
PyObject_HEAD
PyObject *md_dict;
- /* ommit other values, we only want the dict. */
+ /* omit other values, we only want the dict. */
} PyModuleObject;
#endif
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index 75fe05ae2f5..ae3476f5802 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -947,7 +947,7 @@ static PyObject *Quaternion_magnitude_get(QuaternionObject *self, void *UNUSED(c
if (BaseMath_ReadCallback(self) == -1)
return NULL;
- return PyFloat_FromDouble(sqrt(dot_qtqt(self->quat, self->quat)));
+ return PyFloat_FromDouble(sqrtf(dot_qtqt(self->quat, self->quat)));
}
PyDoc_STRVAR(Quaternion_angle_doc,
diff --git a/source/blender/python/rna_dump.py b/source/blender/python/rna_dump.py
index 15cc60d997e..7259ceb67a0 100644
--- a/source/blender/python/rna_dump.py
+++ b/source/blender/python/rna_dump.py
@@ -1,22 +1,22 @@
- # ***** BEGIN GPL LICENSE BLOCK *****
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License
- # as published by the Free Software Foundation; either version 2
- # of the License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software Foundation,
- # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- #
- # Contributor(s): Campbell Barton
- #
- # #**** END GPL LICENSE BLOCK #****
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributor(s): Campbell Barton
+#
+# ##### END GPL LICENSE BLOCK #####
# <pep8 compliant>
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index 8e326e770fc..e516c954737 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -162,6 +162,10 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
+if(WITH_CYCLES AND WITH_CYCLES_DEBUG)
+ add_definitions(-DWITH_CYCLES_DEBUG)
+endif()
+
if(APPLE)
# SSE math is enabled by default on x86_64
if(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
diff --git a/source/blender/render/SConscript b/source/blender/render/SConscript
index 297e4fcecd4..7f459444a39 100644
--- a/source/blender/render/SConscript
+++ b/source/blender/render/SConscript
@@ -103,6 +103,9 @@ if env['WITH_BF_GAMEENGINE']:
if env['WITH_BF_INTERNATIONAL']:
defs.append('WITH_INTERNATIONAL')
+if env['WITH_BF_CYCLES'] and env['WITH_BF_CYCLES_DEBUG']:
+ defs.append('WITH_CYCLES_DEBUG')
+
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index 24f8cbee401..4b0473f7483 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -60,6 +60,7 @@ struct BakePixel;
#define RE_USE_SHADING_NODES 16
#define RE_USE_EXCLUDE_LAYERS 32
#define RE_USE_SAVE_BUFFERS 64
+#define RE_USE_TEXTURE_PREVIEW 128
/* RenderEngine.flag */
#define RE_ENGINE_ANIMATION 1
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index 3b54de4c943..61795c2c173 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -72,8 +72,13 @@ typedef struct RenderPass {
char chan_id[8]; /* amount defined in openexr_multi.h */
float *rect;
int rectx, recty;
+ int debug_type;
} RenderPass;
+enum {
+ RENDER_PASS_DEBUG_BVH_TRAVERSAL_STEPS = 0,
+};
+
/* a renderlayer is a full image, but with all passes and samples */
/* size of the rects is defined in RenderResult */
/* after render, the Combined pass is in rectf, for renderlayers read from files it is a real pass */
diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp
index 24804b8c0ad..6cbb0761358 100644
--- a/source/blender/render/intern/raytrace/rayobject_octree.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp
@@ -657,7 +657,7 @@ static void RE_rayobject_octree_done(RayObject *tree)
oc->ocfacy = (oc->ocres - 0.1f) / t01;
oc->ocfacz = (oc->ocres - 0.1f) / t02;
- oc->ocsize = sqrt(t00 * t00 + t01 * t01 + t02 * t02); /* global, max size octree */
+ oc->ocsize = sqrtf(t00 * t00 + t01 * t01 + t02 * t02); /* global, max size octree */
for (c = 0; c < oc->ro_nodes_used; c++) {
octree_fill_rayface(oc, oc->ro_nodes[c]);
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index e6f054583b1..69dd9607c3b 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -762,7 +762,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par
w= vec[2]*re->winmat[2][3] + re->winmat[3][3];
dx= re->winx*cross[0]*re->winmat[0][0];
dy= re->winy*cross[1]*re->winmat[1][1];
- w= sqrt(dx*dx + dy*dy)/w;
+ w = sqrtf(dx * dx + dy * dy) / w;
if (w!=0.0f) {
float fac;
@@ -927,7 +927,7 @@ static void static_particle_strand(Render *re, ObjectRen *obr, Material *ma, Par
w= vec[2]*re->winmat[2][3] + re->winmat[3][3];
dx= re->winx*dvec[0]*re->winmat[0][0]/w;
dy= re->winy*dvec[1]*re->winmat[1][1]/w;
- w= sqrt(dx*dx + dy*dy);
+ w = sqrtf(dx * dx + dy * dy);
if (dot_v3v3(anor, nor)<sd->adapt_angle && w>sd->adapt_pix) {
vlr= RE_findOrAddVlak(obr, obr->totvlak++);
vlr->flag= flag;
@@ -3796,8 +3796,8 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
normalize_v3(lar->imat[1]);
normalize_v3(lar->imat[2]);
- xn= saacos(lar->spotsi);
- xn= sin(xn)/cos(xn);
+ xn = saacos(lar->spotsi);
+ xn = sinf(xn) / cosf(xn);
lar->spottexfac= 1.0f/(xn);
if (lar->mode & LA_ONLYSHADOW) {
@@ -3820,7 +3820,7 @@ static GroupObject *add_render_lamp(Render *re, Object *ob)
/* z factor, for a normalized volume */
angle= saacos(lar->spotsi);
xn= lar->spotsi;
- yn= sin(angle);
+ yn = sinf(angle);
lar->sh_zfac= yn/xn;
/* pre-scale */
lar->sh_invcampos[2]*= lar->sh_zfac;
@@ -5438,7 +5438,7 @@ static float *calculate_strandsurface_speedvectors(Render *re, ObjectInstanceRen
{
if (mesh->co && mesh->prevco && mesh->nextco) {
float winsq= (float)re->winx*(float)re->winy; /* int's can wrap on large images */
- float winroot= sqrt(winsq);
+ float winroot= sqrtf(winsq);
float (*winspeed)[4];
float ho[4], prevho[4], nextho[4], winmat[4][4], vec[2];
int a;
@@ -5477,7 +5477,7 @@ static void calculate_speedvectors(Render *re, ObjectInstanceRen *obi, float *ve
StrandSurface *mesh= NULL;
float *speed, (*winspeed)[4]=NULL, ho[4], winmat[4][4];
float *co1, *co2, *co3, *co4, w[4];
- float winsq= (float)re->winx*(float)re->winy, winroot= sqrt(winsq); /* int's can wrap on large images */
+ float winsq = (float)re->winx * (float)re->winy, winroot = sqrtf(winsq); /* int's can wrap on large images */
int a, *face, *index;
if (obi->flag & R_TRANSFORMED)
@@ -5544,7 +5544,7 @@ static int load_fluidsimspeedvectors(Render *re, ObjectInstanceRen *obi, float *
VertRen *ver= NULL;
float *speed, div, zco[2], avgvel[4] = {0.0, 0.0, 0.0, 0.0};
float zmulx= re->winx/2, zmuly= re->winy/2, len;
- float winsq= (float)re->winx*(float)re->winy, winroot= sqrt(winsq); /* int's can wrap on large images */
+ float winsq = (float)re->winx * (float)re->winy, winroot= sqrtf(winsq); /* int's can wrap on large images */
int a, j;
float hoco[4], ho[4], fsvec[4], camco[4];
float mat[4][4], winmat[4][4];
diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c
index 5fd4747f19b..353ba5d5caa 100644
--- a/source/blender/render/intern/source/initrender.c
+++ b/source/blender/render/intern/source/initrender.c
@@ -190,7 +190,7 @@ static float calc_weight(Render *re, float *weight, int i, int j)
for (a = 0; a < re->osa; a++) {
x = re->jit[a][0] + i;
y = re->jit[a][1] + j;
- dist = sqrt(x * x + y * y);
+ dist = sqrtf(x * x + y * y);
weight[a] = 0.0;
diff --git a/source/blender/render/intern/source/multires_bake.c b/source/blender/render/intern/source/multires_bake.c
index 4ac1593d1bb..6ba85ea5329 100644
--- a/source/blender/render/intern/source/multires_bake.c
+++ b/source/blender/render/intern/source/multires_bake.c
@@ -42,6 +42,7 @@
#include "BLI_threads.h"
#include "BKE_ccg.h"
+#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_image.h"
#include "BKE_multires.h"
@@ -1154,10 +1155,10 @@ static void apply_ao_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, void
/* this gives results identical to the so-called cosine
* weighted distribution relative to the north pole.
*/
- float SiPhi = sqrt(SiSqPhi);
+ float SiPhi = sqrtf(SiSqPhi);
float CoPhi = SiSqPhi < 1.0f ? sqrtf(1.0f - SiSqPhi) : 0;
- float CoThe = cos(Theta);
- float SiThe = sin(Theta);
+ float CoThe = cosf(Theta);
+ float SiThe = sinf(Theta);
const float dx = CoThe * CoPhi;
const float dy = SiThe * CoPhi;
@@ -1297,6 +1298,7 @@ static void finish_images(MultiresBakeRender *bkr, MultiresBakeResult *result)
}
BKE_image_release_ibuf(ima, ibuf, NULL);
+ DAG_id_tag_update(&ima->id, 0);
}
}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 32bd67cb1f2..7b43c77537f 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -699,25 +699,27 @@ static void render_result_rescale(Render *re)
RR_USE_MEM,
RR_ALL_LAYERS);
- dst_rectf = re->result->rectf;
- if (dst_rectf == NULL) {
- RenderLayer *rl;
- rl = render_get_active_layer(re, re->result);
- if (rl != NULL) {
- dst_rectf = rl->rectf;
+ if (re->result != NULL) {
+ dst_rectf = re->result->rectf;
+ if (dst_rectf == NULL) {
+ RenderLayer *rl;
+ rl = render_get_active_layer(re, re->result);
+ if (rl != NULL) {
+ dst_rectf = rl->rectf;
+ }
}
- }
- scale_x = (float) result->rectx / re->result->rectx;
- scale_y = (float) result->recty / re->result->recty;
- for (x = 0; x < re->result->rectx; ++x) {
- for (y = 0; y < re->result->recty; ++y) {
- int src_x = x * scale_x,
- src_y = y * scale_y;
- int dst_index = y * re->result->rectx + x,
- src_index = src_y * result->rectx + src_x;
- copy_v4_v4(dst_rectf + dst_index * 4,
- src_rectf + src_index * 4);
+ scale_x = (float) result->rectx / re->result->rectx;
+ scale_y = (float) result->recty / re->result->recty;
+ for (x = 0; x < re->result->rectx; ++x) {
+ for (y = 0; y < re->result->recty; ++y) {
+ int src_x = x * scale_x,
+ src_y = y * scale_y;
+ int dst_index = y * re->result->rectx + x,
+ src_index = src_y * result->rectx + src_x;
+ copy_v4_v4(dst_rectf + dst_index * 4,
+ src_rectf + src_index * 4);
+ }
}
}
}
@@ -1013,8 +1015,8 @@ static bool find_next_pano_slice(Render *re, int *slice, int *minx, rctf *viewpl
/* rotate database according to part coordinates */
project_renderdata(re, projectverto, 1, -R.panodxp * phi, 1);
- R.panosi = sin(R.panodxp * phi);
- R.panoco = cos(R.panodxp * phi);
+ R.panosi = sinf(R.panodxp * phi);
+ R.panoco = cosf(R.panodxp * phi);
}
(*slice)++;
@@ -1638,6 +1640,10 @@ static void do_render_fields_blur_3d(Render *re)
if (re->r.mode & R_BORDER) {
if ((re->r.mode & R_CROP) == 0) {
RenderResult *rres;
+
+ /* backup */
+ const rcti orig_disprect = re->disprect;
+ const int orig_rectx = re->rectx, orig_recty = re->recty;
BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE);
@@ -1660,6 +1666,11 @@ static void do_render_fields_blur_3d(Render *re)
re->display_init(re->dih, re->result);
re->display_update(re->duh, re->result, NULL);
+
+ /* restore the disprect from border */
+ re->disprect = orig_disprect;
+ re->rectx = orig_rectx;
+ re->recty = orig_recty;
}
else {
/* set offset (again) for use in compositor, disprect was manipulated. */
@@ -2651,7 +2662,16 @@ bool RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *
}
#endif
}
-
+
+#ifdef WITH_FREESTYLE
+ if (scene->r.mode & R_EDGE_FRS) {
+ if (scene->r.mode & R_FIELDS) {
+ BKE_report(reports, RPT_ERROR, "Fields not supported in Freestyle");
+ return false;
+ }
+ }
+#endif
+
/* layer flag tests */
if (!render_scene_has_layers_to_render(scene)) {
BKE_report(reports, RPT_ERROR, "All render layers are disabled");
diff --git a/source/blender/render/intern/source/pixelshading.c b/source/blender/render/intern/source/pixelshading.c
index 09a6a6374be..014df802a78 100644
--- a/source/blender/render/intern/source/pixelshading.c
+++ b/source/blender/render/intern/source/pixelshading.c
@@ -160,7 +160,7 @@ static void render_lighting_halo(HaloRen *har, float col_r[3])
x = max_ff(fabsf(lvrot[0]/lvrot[2]), fabsf(lvrot[1]/lvrot[2]));
/* 1.0/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
- inpr= 1.0/(sqrt(1.0f+x*x));
+ inpr = 1.0 / (sqrtf(1.0f + x * x));
}
else inpr= 0.0;
}
@@ -206,7 +206,7 @@ static void render_lighting_halo(HaloRen *har, float col_r[3])
/* dot product and reflectivity*/
- inp = 1.0 - fabs(dot_v3v3(vn, lv));
+ inp = 1.0 - fabsf(dot_v3v3(vn, lv));
/* inp= cos(0.5*M_PI-acos(inp)); */
@@ -329,7 +329,7 @@ int shadeHaloFloat(HaloRen *har, float col[4], int zz,
}
}
- radist= sqrt(dist);
+ radist = sqrtf(dist);
/* watch it: not used nicely: flarec is set at zero in pixstruct */
if (flarec) har->pixels+= (int)(har->rad-radist);
@@ -366,17 +366,15 @@ int shadeHaloFloat(HaloRen *har, float col[4], int zz,
else dist= dist/har->radsq;
if (har->type & HA_FLARECIRC) {
-
- dist= 0.5+fabs(dist-0.5f);
-
+ dist = 0.5 + fabsf(dist - 0.5f);
}
if (har->hard>=30) {
- dist= sqrt(dist);
+ dist = sqrtf(dist);
if (har->hard>=40) {
- dist= sinf(dist*(float)M_PI_2);
+ dist = sinf(dist*(float)M_PI_2);
if (har->hard>=50) {
- dist= sqrt(dist);
+ dist = sqrtf(dist);
}
}
}
@@ -399,7 +397,7 @@ int shadeHaloFloat(HaloRen *har, float col[4], int zz,
rc= hashvectf + (ofs % 768);
- fac= fabs( (xn)*rc[0]+(yn)*rc[1]);
+ fac = fabsf((xn) * rc[0] + (yn) * rc[1]);
if (fac< 1.0f )
linef+= (1.0f-fac);
@@ -411,15 +409,15 @@ int shadeHaloFloat(HaloRen *har, float col[4], int zz,
if (har->starpoints) {
float ster, angle;
/* rotation */
- angle= atan2(yn, xn);
- angle*= (1.0f+0.25f*har->starpoints);
+ angle = atan2f(yn, xn);
+ angle *= (1.0f+0.25f*har->starpoints);
co= cosf(angle);
si= sinf(angle);
angle= (co*xn+si*yn)*(co*yn-si*xn);
- ster= fabs(angle);
+ ster = fabsf(angle);
if (ster>1.0f) {
ster= (har->rad)/(ster);
diff --git a/source/blender/render/intern/source/pointdensity.c b/source/blender/render/intern/source/pointdensity.c
index 799f7fa2f2e..ac2e85a33b3 100644
--- a/source/blender/render/intern/source/pointdensity.c
+++ b/source/blender/render/intern/source/pointdensity.c
@@ -384,7 +384,7 @@ static void accum_density(void *userdata, int index, float squared_dist)
else if (pdr->falloff_type == TEX_PD_FALLOFF_CONSTANT)
density = pdr->squared_radius;
else if (pdr->falloff_type == TEX_PD_FALLOFF_ROOT)
- density = sqrt(dist);
+ density = sqrtf(dist);
else if (pdr->falloff_type == TEX_PD_FALLOFF_PARTICLE_AGE) {
if (pdr->point_data_used & POINT_DATA_LIFE)
density = dist*MIN2(pdr->point_data[pdr->offset + index], 1.0f);
diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c
index 7e56d93f23b..ff1f502cc1a 100644
--- a/source/blender/render/intern/source/rayshade.c
+++ b/source/blender/render/intern/source/rayshade.c
@@ -651,7 +651,7 @@ static float shade_by_transmission(Isect *is, ShadeInput *shi, ShadeResult *shr)
const float dx= shi->co[0] - is->start[0];
const float dy= shi->co[1] - is->start[1];
const float dz= shi->co[2] - is->start[2];
- d= sqrt(dx*dx+dy*dy+dz*dz);
+ d = sqrtf(dx * dx + dy * dy + dz * dz);
if (d > shi->mat->tx_limit)
d= shi->mat->tx_limit;
@@ -1117,7 +1117,7 @@ static void QMC_samplePhong(float vec[3], QMCSampler *qsa, int thread, int num,
phi = s[0]*2*M_PI;
pz = pow(s[1], blur);
- sqr = sqrt(1.0f-pz*pz);
+ sqr = sqrtf(1.0f - pz * pz);
vec[0] = (float)(cosf(phi)*sqr);
vec[1] = (float)(sinf(phi)*sqr);
@@ -1281,7 +1281,7 @@ static float get_avg_speed(ShadeInput *shi)
post_x = (shi->winspeed[2] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[2];
post_y = (shi->winspeed[3] == PASS_VECTOR_MAX)?0.0f:shi->winspeed[3];
- speedavg = (sqrt(pre_x*pre_x + pre_y*pre_y) + sqrt(post_x*post_x + post_y*post_y)) / 2.0;
+ speedavg = (sqrtf(pre_x * pre_x + pre_y * pre_y) + sqrtf(post_x * post_x + post_y * post_y)) / 2.0;
return speedavg;
}
@@ -1786,10 +1786,10 @@ static float *sphere_sampler(int type, int resol, int thread, int xs, int ys, in
sphere= threadsafe_table_sphere(0, thread, xs, ys, tot);
/* random rotation */
- ang= BLI_thread_frand(thread);
- sinfi= sin(ang); cosfi= cos(ang);
- ang= BLI_thread_frand(thread);
- sint= sin(ang); cost= cos(ang);
+ ang = BLI_thread_frand(thread);
+ sinfi = sinf(ang); cosfi = cosf(ang);
+ ang = BLI_thread_frand(thread);
+ sint = sinf(ang); cost = cosf(ang);
vec= R.wrld.aosphere;
vec1= sphere;
@@ -2371,9 +2371,9 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, const float lampco[
mul_m3_v3(lar->mat, vec);
/* set start and vec */
- isec->dir[0] = vec[0]+lampco[0]-isec->start[0];
- isec->dir[1] = vec[1]+lampco[1]-isec->start[1];
- isec->dir[2] = vec[2]+lampco[2]-isec->start[2];
+ isec->dir[0] = vec[0]+lampco[0]-shi->co[0];
+ isec->dir[1] = vec[1]+lampco[1]-shi->co[1];
+ isec->dir[2] = vec[2]+lampco[2]-shi->co[2];
RE_instance_rotate_ray_dir(shi->obi, isec);
@@ -2406,9 +2406,9 @@ static void ray_shadow_jitter(ShadeInput *shi, LampRen *lar, const float lampco[
else {
/* sqrt makes nice umbra effect */
if (lar->ray_samp_type & LA_SAMP_UMBRA)
- shadfac[3]= sqrt(1.0f-fac/div);
+ shadfac[3] = sqrtf(1.0f - fac / div);
else
- shadfac[3]= 1.0f-fac/div;
+ shadfac[3] = 1.0f - fac / div;
}
}
/* extern call from shade_lamp_loop */
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index d8410fbe257..24797521435 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -48,6 +48,9 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_report.h"
+#ifdef WITH_CYCLES_DEBUG
+# include "BKE_scene.h"
+#endif
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -402,7 +405,7 @@ static int passtype_from_name(const char *str)
/********************************** New **************************************/
-static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
+static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype)
{
const char *typestr = get_pass_name(passtype, 0);
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), typestr);
@@ -438,8 +441,34 @@ static void render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channel
rect[x] = 10e10;
}
}
+ return rpass;
}
+#ifdef WITH_CYCLES_DEBUG
+static const char *debug_pass_type_name_get(int debug_type)
+{
+ switch (debug_type) {
+ case RENDER_PASS_DEBUG_BVH_TRAVERSAL_STEPS:
+ return "BVH Traversal Steps";
+ }
+ return "Unknown";
+}
+
+static RenderPass *render_layer_add_debug_pass(RenderResult *rr,
+ RenderLayer *rl,
+ int channels,
+ int pass_type,
+ int debug_type)
+{
+ RenderPass *rpass = render_layer_add_pass(rr, rl, channels, pass_type);
+ rpass->debug_type = debug_type;
+ BLI_strncpy(rpass->name,
+ debug_pass_type_name_get(debug_type),
+ sizeof(rpass->name));
+ return rpass;
+}
+#endif
+
/* called by main render as well for parts */
/* will read info from Render *re to define layers */
/* called in threads */
@@ -578,6 +607,13 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT);
if (srl->passflag & SCE_PASS_SUBSURFACE_COLOR)
render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR);
+
+#ifdef WITH_CYCLES_DEBUG
+ if(BKE_scene_use_new_shading_nodes(re->scene)) {
+ render_layer_add_debug_pass(rr, rl, 1, SCE_PASS_DEBUG,
+ RENDER_PASS_DEBUG_BVH_TRAVERSAL_STEPS);
+ }
+#endif
}
/* sss, previewrender and envmap don't do layers, so we make a default one */
if (BLI_listbase_is_empty(&rr->layers) && !(layername && layername[0])) {
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index dd14c2495e8..0e61c3e796a 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -212,10 +212,10 @@ static int blend(Tex *tex, const float texvec[3], TexResult *texres)
texres->tin= (2.0f+x+y)/4.0f;
}
else if (tex->stype==TEX_RAD) { /* radial */
- texres->tin= (atan2(y, x) / (2*M_PI) + 0.5);
+ texres->tin = (atan2f(y, x) / (2 * M_PI) + 0.5f);
}
else { /* sphere TEX_SPHERE */
- texres->tin= 1.0-sqrt(x*x+ y*y+texvec[2]*texvec[2]);
+ texres->tin = 1.0 - sqrtf(x * x + y * y + texvec[2] * texvec[2]);
if (texres->tin<0.0f) texres->tin= 0.0f;
if (tex->stype==TEX_HALO) texres->tin*= texres->tin; /* halo */
}
@@ -266,8 +266,8 @@ static int clouds(Tex *tex, const float texvec[3], TexResult *texres)
/* creates a sine wave */
static float tex_sin(float a)
{
- a = 0.5 + 0.5*sin(a);
-
+ a = 0.5 + 0.5 * sinf(a);
+
return a;
}
@@ -366,10 +366,10 @@ static float marble_int(Tex *tex, float x, float y, float z)
if (mt>=TEX_SOFT) { /* TEX_SOFT always true */
mi = waveform[wf](mi);
if (mt==TEX_SHARP) {
- mi = sqrt(mi);
+ mi = sqrtf(mi);
}
else if (mt==TEX_SHARPER) {
- mi = sqrt(sqrt(mi));
+ mi = sqrtf(sqrtf(mi));
}
}
@@ -408,41 +408,41 @@ static int magic(Tex *tex, const float texvec[3], TexResult *texres)
n= tex->noisedepth;
turb= tex->turbul/5.0f;
- x= sin( ( texvec[0]+texvec[1]+texvec[2])*5.0f );
- y= cos( (-texvec[0]+texvec[1]-texvec[2])*5.0f );
- z= -cos( (-texvec[0]-texvec[1]+texvec[2])*5.0f );
+ x = sinf(( texvec[0] + texvec[1] + texvec[2]) * 5.0f);
+ y = cosf((-texvec[0] + texvec[1] - texvec[2]) * 5.0f);
+ z = -cosf((-texvec[0] - texvec[1] + texvec[2]) * 5.0f);
if (n>0) {
x*= turb;
y*= turb;
z*= turb;
- y= -cos(x-y+z);
+ y= -cosf(x-y+z);
y*= turb;
if (n>1) {
- x= cos(x-y-z);
+ x= cosf(x-y-z);
x*= turb;
if (n>2) {
- z= sin(-x-y-z);
+ z= sinf(-x-y-z);
z*= turb;
if (n>3) {
- x= -cos(-x+y-z);
+ x= -cosf(-x+y-z);
x*= turb;
if (n>4) {
- y= -sin(-x+y+z);
+ y= -sinf(-x+y+z);
y*= turb;
if (n>5) {
- y= -cos(-x+y+z);
+ y= -cosf(-x+y+z);
y*= turb;
if (n>6) {
- x= cos(x+y+z);
+ x= cosf(x+y+z);
x*= turb;
if (n>7) {
- z= sin(x+y-z);
+ z= sinf(x+y-z);
z*= turb;
if (n>8) {
- x= -cos(-x-y+z);
+ x= -cosf(-x-y+z);
x*= turb;
if (n>9) {
- y= -sin(x-y+z);
+ y= -sinf(x-y+z);
y*= turb;
}
}
@@ -2348,8 +2348,8 @@ void do_material_tex(ShadeInput *shi, Render *re)
copy_v3_v3(texres.nor, &texres.tr);
}
else {
- float co_nor= 0.5*cos(texres.tin-0.5f);
- float si= 0.5*sin(texres.tin-0.5f);
+ float co_nor= 0.5f * cosf(texres.tin - 0.5f);
+ float si = 0.5f * sinf(texres.tin - 0.5f);
float f1, f2;
f1= shi->vn[0];
@@ -3396,8 +3396,11 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r
col[0]= texres.tr*la->energy;
col[1]= texres.tg*la->energy;
col[2]= texres.tb*la->energy;
-
- texture_rgb_blend(col_r, col, col_r, texres.tin, mtex->colfac, mtex->blendtype);
+
+ if (effect & LA_SHAD_TEX)
+ texture_rgb_blend(col_r, col, col_r, texres.tin, mtex->shadowfac, mtex->blendtype);
+ else
+ texture_rgb_blend(col_r, col, col_r, texres.tin, mtex->colfac, mtex->blendtype);
}
}
}
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 27bc449dce3..a67140c6334 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -1906,9 +1906,9 @@ static void renderflare(RenderResult *rr, float *rectf, HaloRen *har)
fla.hard= 20.0f + fabsf(70.0f*rc[7]);
fla.tex= 0;
- type= (int)(fabs(3.9f*rc[6]));
+ type= (int)(fabsf(3.9f*rc[6]));
- fla.rad= ma->subsize*sqrtf(fabs(2.0f*har->rad*rc[4]));
+ fla.rad = ma->subsize * sqrtf(fabsf(2.0f * har->rad * rc[4]));
if (type==3) {
fla.rad*= 3.0f;
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 6a3787289d8..46c504aaabf 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -992,10 +992,10 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma,
xn= har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]);
yn= har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]);
if (xn==0.0f || (xn==0.0f && yn==0.0f)) zn= 0.0f;
- else zn= atan2(yn, xn);
+ else zn = atan2f(yn, xn);
- har->sin= sin(zn);
- har->cos= cos(zn);
+ har->sin = sinf(zn);
+ har->cos = cosf(zn);
zn= len_v3v3(vec1, vec);
har->hasize= vectsize*zn + (1.0f-vectsize)*hasize;
@@ -1112,10 +1112,10 @@ HaloRen *RE_inithalo_particle(Render *re, ObjectRen *obr, DerivedMesh *dm, Mater
xn= har->xs - 0.5f*re->winx*(hoco1[0]/hoco1[3]);
yn= har->ys - 0.5f*re->winy*(hoco1[1]/hoco1[3]);
if (xn==0.0f || (xn==0.0f && yn==0.0f)) zn= 0.0;
- else zn= atan2(yn, xn);
+ else zn = atan2f(yn, xn);
- har->sin= sin(zn);
- har->cos= cos(zn);
+ har->sin = sinf(zn);
+ har->cos = cosf(zn);
zn= len_v3v3(vec1, vec)*0.5f;
har->hasize= vectsize*zn + (1.0f-vectsize)*hasize;
@@ -1284,8 +1284,8 @@ void project_renderdata(Render *re,
if (do_pano) {
float panophi= xoffs;
- re->panosi= sin(panophi);
- re->panoco= cos(panophi);
+ re->panosi = sinf(panophi);
+ re->panoco = cosf(panophi);
}
for (obr=re->objecttable.first; obr; obr=obr->next) {
diff --git a/source/blender/render/intern/source/shadbuf.c b/source/blender/render/intern/source/shadbuf.c
index aa420d7e7c8..9d83ff1d7e8 100644
--- a/source/blender/render/intern/source/shadbuf.c
+++ b/source/blender/render/intern/source/shadbuf.c
@@ -536,7 +536,7 @@ static void compress_shadowbuf(ShadBuf *shb, int *rectz, int square)
if (x< a) minx= x+15-a;
else minx= x-a;
- dist= sqrt( (float)(minx*minx+miny*miny) );
+ dist = sqrtf((float)(minx * minx + miny * miny));
if (square==0 && dist>(float)(a+12)) { /* 12, tested with a onlyshadow lamp */
a= 256; verg= 0; /* 0x80000000; */ /* 0x7FFFFFFF; */
@@ -1685,7 +1685,7 @@ static int point_behind_strand(const float p[3], BSPFace *face)
if (face->len==0.0f) {
rc[0]= p[0]-face->vec1[0];
rc[1]= p[1]-face->vec1[1];
- dist= (float)(sqrt(rc[0]*rc[0]+ rc[1]*rc[1]));
+ dist = len_v2(rc);
if (dist < face->radline)
return 1;
@@ -1699,10 +1699,10 @@ static int point_behind_strand(const float p[3], BSPFace *face)
pt[0]= lambda*face->rc[0]+face->vec1[0];
pt[1]= lambda*face->rc[1]+face->vec1[1];
-
+
rc[0]= pt[0]-p[0];
rc[1]= pt[1]-p[1];
- dist= sqrtf(rc[0]*rc[0]+ rc[1]*rc[1]);
+ dist = len_v2(rc);
if (dist < face->radline) {
float zval= face->vec1[2] + lambda*face->rc[2];
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index 427d0eeed11..f909c585561 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -144,7 +144,7 @@ float mistfactor(float zcor, float const co[3])
/* pass */
}
else {
- fac = sqrt(fac);
+ fac = sqrtf(fac);
}
}
else {
@@ -338,9 +338,9 @@ static void spothalo(struct LampRen *lar, ShadeInput *shi, float *intens)
/* now we have 2 points, make three lengths with it */
- a= sqrt(p1[0]*p1[0]+p1[1]*p1[1]+p1[2]*p1[2]);
- b= sqrt(p2[0]*p2[0]+p2[1]*p2[1]+p2[2]*p2[2]);
- c= len_v3v3(p1, p2);
+ a = len_v3(p1);
+ b = len_v3(p2);
+ c = len_v3v3(p1, p2);
a/= ladist;
a= sqrt(a);
@@ -640,7 +640,7 @@ static float Blinn_Spec(const float n[3], const float l[3], const float v[3], fl
/* conversion from 'hardness' (1-255) to 'spec_power' (50 maps at 0.1) */
if (spec_power<100.0f)
- spec_power= sqrt(1.0f/spec_power);
+ spec_power = sqrtf(1.0f / spec_power);
else spec_power= 10.0f/spec_power;
h[0]= v[0]+l[0];
@@ -731,7 +731,7 @@ static float WardIso_Spec(const float n[3], const float l[3], const float v[3],
if (tangent) nl = sasqrt(1.0f - nl*nl);
if (nl<=0.0f) nl = 0.001f;
- angle = tan(saacos(nh));
+ angle = tanf(saacos(nh));
alpha = MAX2(rms, 0.001f);
i= nl * (1.0f/(4.0f*(float)M_PI*alpha*alpha)) * (expf( -(angle*angle)/(alpha*alpha))/(sqrtf(nv*nl)));
@@ -746,7 +746,7 @@ static float Toon_Diff(const float n[3], const float l[3], const float UNUSED(v[
rslt = n[0]*l[0] + n[1]*l[1] + n[2]*l[2];
- ang = saacos( (double)(rslt) );
+ ang = saacos(rslt);
if ( ang < size ) rslt = 1.0f;
else if ( ang >= (size + smooth) || smooth == 0.0f ) rslt = 0.0f;
@@ -1257,7 +1257,7 @@ float lamp_get_visibility(LampRen *lar, const float co[3], float lv[3], float *d
x = max_ff(fabsf(lvrot[0]/lvrot[2]), fabsf(lvrot[1]/lvrot[2]));
/* 1.0f/(sqrt(1+x*x)) is equivalent to cos(atan(x)) */
- inpr= 1.0f/(sqrt(1.0f+x*x));
+ inpr = 1.0f / (sqrtf(1.0f + x * x));
}
else inpr= 0.0f;
}
@@ -1494,11 +1494,14 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int
add_to_diffuse(shr->shad, shi, is, lashdw[0]*(i_noshad-i)*lacol[0], lashdw[1]*(i_noshad-i)*lacol[1], lashdw[2]*(i_noshad-i)*lacol[2]);
}
if (i_noshad>0.0f) {
- if (passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW)) {
+ if (passflag & (SCE_PASS_DIFFUSE|SCE_PASS_SHADOW) ||
+ ((passflag & SCE_PASS_COMBINED) && !(shi->combinedflag & SCE_PASS_SHADOW)))
+ {
add_to_diffuse(shr->diff, shi, is, i_noshad*lacol[0], i_noshad*lacol[1], i_noshad*lacol[2]);
}
- else
+ else {
copy_v3_v3(shr->diff, shr->shad);
+ }
}
}
@@ -1648,7 +1651,8 @@ static void shade_lamp_loop_only_shadow(ShadeInput *shi, ShadeResult *shr)
else { /* shadowonly_flag == MA_SO_SHADED */
/* Use shaded value */
accum = 1.0f - shaded;
- }}
+ }
+ }
shr->alpha= (shi->alpha)*(accum);
if (shr->alpha<0.0f) shr->alpha=0.0f;
@@ -1714,7 +1718,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
*/
const int color_passes =
SCE_PASS_COMBINED | SCE_PASS_RGBA | SCE_PASS_DIFFUSE | SCE_PASS_SPEC |
- SCE_PASS_REFLECT | SCE_PASS_NORMAL | SCE_PASS_REFRACT | SCE_PASS_EMIT;
+ SCE_PASS_REFLECT | SCE_PASS_NORMAL | SCE_PASS_REFRACT | SCE_PASS_EMIT | SCE_PASS_SHADOW;
Material *ma= shi->mat;
int passflag= shi->passflag;
@@ -1889,7 +1893,7 @@ void shade_lamp_loop(ShadeInput *shi, ShadeResult *shr)
}
if (shi->combinedflag & SCE_PASS_SHADOW)
- copy_v3_v3(shr->diffshad, shr->shad); /* note, no ';' ! */
+ copy_v3_v3(shr->diffshad, shr->shad);
else
copy_v3_v3(shr->diffshad, shr->diff);
diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c
index 52d3815c4ad..7e9003aaee7 100644
--- a/source/blender/render/intern/source/sss.c
+++ b/source/blender/render/intern/source/sss.c
@@ -165,7 +165,7 @@ static float f_Rd(float alpha_, float A, float ro)
{
float sq;
- sq= sqrt(3.0f*(1.0f - alpha_));
+ sq = sqrtf(3.0f * (1.0f - alpha_));
return (alpha_/2.0f)*(1.0f + expf((-4.0f/3.0f)*A*sq))*expf(-sq) - ro;
}
@@ -212,8 +212,8 @@ static float Rd_rsquare(ScatterSettings *ss, float rr)
{
float sr, sv, Rdr, Rdv;
- sr= sqrt(rr + ss->zr*ss->zr);
- sv= sqrt(rr + ss->zv*ss->zv);
+ sr = sqrtf(rr + ss->zr * ss->zr);
+ sv = sqrtf(rr + ss->zv * ss->zv);
Rdr= ss->zr*(1.0f + ss->sigma*sr)*expf(-ss->sigma*sr)/(sr*sr*sr);
Rdv= ss->zv*(1.0f + ss->sigma*sv)*expf(-ss->sigma*sv)/(sv*sv*sv);
@@ -241,7 +241,7 @@ static void approximate_Rd_rgb(ScatterSettings **ss, float rr, float *rd)
/* pass */
}
else if (rr > RD_TABLE_RANGE) {
- rr= sqrt(rr);
+ rr = sqrtf(rr);
indexf= rr*(RD_TABLE_SIZE/RD_TABLE_RANGE_2);
index= (int)indexf;
idxf= (float)index;
@@ -286,7 +286,7 @@ static void build_Rd_table(ScatterSettings *ss)
r= i*(RD_TABLE_RANGE/RD_TABLE_SIZE);
/*if (r < ss->invsigma_t_*ss->invsigma_t_)
r= ss->invsigma_t_*ss->invsigma_t_;*/
- ss->tableRd[i]= Rd(ss, sqrt(r));
+ ss->tableRd[i]= Rd(ss, sqrtf(r));
r= i*(RD_TABLE_RANGE_2/RD_TABLE_SIZE);
/*if (r < ss->invsigma_t_)
diff --git a/source/blender/render/intern/source/strand.c b/source/blender/render/intern/source/strand.c
index 50343cfaa0b..485680da76f 100644
--- a/source/blender/render/intern/source/strand.c
+++ b/source/blender/render/intern/source/strand.c
@@ -145,7 +145,7 @@ void strand_eval_point(StrandSegment *sseg, StrandPoint *spoint)
w= spoint->co[2]*strandbuf->winmat[2][3] + strandbuf->winmat[3][3];
dx= strandbuf->winx*cross[0]*strandbuf->winmat[0][0]/w;
dy= strandbuf->winy*cross[1]*strandbuf->winmat[1][1]/w;
- w= sqrt(dx*dx + dy*dy);
+ w = sqrtf(dx * dx + dy * dy);
if (w > 0.0f) {
if (strandbuf->flag & R_STRAND_B_UNITS) {
diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c
index 71ef5b8f62f..1836b3f48a7 100644
--- a/source/blender/render/intern/source/sunsky.c
+++ b/source/blender/render/intern/source/sunsky.c
@@ -89,14 +89,14 @@ void ClipColor(float c[3])
* */
static float AngleBetween(float thetav, float phiv, float theta, float phi)
{
- float cospsi = sin(thetav) * sin(theta) * cos(phi - phiv) + cos(thetav) * cos(theta);
+ float cospsi = sinf(thetav) * sinf(theta) * cosf(phi - phiv) + cosf(thetav) * cosf(theta);
if (cospsi > 1.0f)
return 0;
if (cospsi < -1.0f)
return M_PI;
- return acos(cospsi);
+ return acosf(cospsi);
}
/**
@@ -112,7 +112,7 @@ static void DirectionToThetaPhi(float *toSun, float *theta, float *phi)
if (fabsf(*theta) < 1e-5f)
*phi = 0;
else
- *phi = atan2(toSun[1], toSun[0]);
+ *phi = atan2f(toSun[1], toSun[0]);
}
/**
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 28849ed7686..87e546ef24e 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -2951,7 +2951,7 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
dvec2[1]= 0.0f;
}
else {
- speedsq= 1.0f - minspeed/sqrt(speedsq);
+ speedsq = 1.0f - minspeed / sqrtf(speedsq);
dvec2[0]= speedsq*dvec1[0];
dvec2[1]= speedsq*dvec1[1];
}
@@ -3027,7 +3027,7 @@ void RE_zbuf_accumulate_vecblur(NodeBlurData *nbd, int xsize, int ysize, float *
if (maxspeed) {
float speedsq= dvz[0]*dvz[0] + dvz[1]*dvz[1];
if (speedsq > maxspeedsq) {
- speedsq= (float)maxspeed/sqrt(speedsq);
+ speedsq = (float)maxspeed / sqrtf(speedsq);
dvz[0]*= speedsq;
dvz[1]*= speedsq;
}
@@ -3386,7 +3386,7 @@ static int zbuffer_abuf(Render *re, RenderPart *pa, APixstr *APixbuf, ListBase *
projectverto(vec, obwinmat, hoco);
fval= mul*(1.0f+hoco[2]/hoco[3]);
- polygon_offset= (int) fabs(zval - fval );
+ polygon_offset= (int)fabsf(zval - fval);
}
else polygon_offset= 0;
diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c
index 748303f9082..1abe000a86c 100644
--- a/source/blender/windowmanager/intern/wm_keymap.c
+++ b/source/blender/windowmanager/intern/wm_keymap.c
@@ -589,8 +589,12 @@ static void wm_keymap_patch(wmKeyMap *km, wmKeyMap *diff_km)
/* add item */
if (kmdi->add_item) {
+ /* Do not re-add an already existing keymap item! See T42088. */
+ kmi_add = wm_keymap_find_item_equals(km, kmdi->add_item);
+ if (!kmi_add)
+ kmi_add = wm_keymap_find_item_equals_result(km, kmdi->add_item);
/* only if nothing to remove or item to remove found */
- if (!kmdi->remove_item || kmi_remove) {
+ if (!kmi_add && (!kmdi->remove_item || kmi_remove)) {
kmi_add = wm_keymap_item_copy(kmdi->add_item);
kmi_add->flag |= KMI_USER_MODIFIED;
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index bc79879f1f4..b9a79a85455 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1893,7 +1893,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
col = uiLayoutColumn(split, false);
uiItemL(col, IFACE_("Links"), ICON_NONE);
uiItemStringO(col, IFACE_("Support an Open Animation Movie"), ICON_URL, "WM_OT_url_open", "url",
- "http://cloud.blender.org/gooseberry");
+ "https://cloud.blender.org/join");
uiItemStringO(col, IFACE_("Donations"), ICON_URL, "WM_OT_url_open", "url",
"http://www.blender.org/foundation/donation-payment/");
uiItemStringO(col, IFACE_("Credits"), ICON_URL, "WM_OT_url_open", "url",
@@ -2208,7 +2208,7 @@ static void WM_OT_read_homefile(wmOperatorType *ot)
"Load user interface setup from the .blend file");
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
- /* ommit poll to run in background mode */
+ /* omit poll to run in background mode */
}
static void WM_OT_read_factory_settings(wmOperatorType *ot)
@@ -2219,7 +2219,7 @@ static void WM_OT_read_factory_settings(wmOperatorType *ot)
ot->invoke = WM_operator_confirm;
ot->exec = wm_homefile_read_exec;
- /* ommit poll to run in background mode */
+ /* omit poll to run in background mode */
}
/* *************** open file **************** */
@@ -2372,7 +2372,7 @@ static void WM_OT_open_mainfile(wmOperatorType *ot)
ot->exec = wm_open_mainfile_exec;
ot->check = wm_open_mainfile_check;
ot->ui = wm_open_mainfile_ui;
- /* ommit window poll so this can work in background mode */
+ /* omit window poll so this can work in background mode */
WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_OPENFILE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
@@ -2860,7 +2860,7 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot)
ot->invoke = wm_save_as_mainfile_invoke;
ot->exec = wm_save_as_mainfile_exec;
ot->check = blend_save_check;
- /* ommit window poll so this can work in background mode */
+ /* omit window poll so this can work in background mode */
WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
@@ -2936,7 +2936,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot)
ot->invoke = wm_save_mainfile_invoke;
ot->exec = wm_save_as_mainfile_exec;
ot->check = blend_save_check;
- /* ommit window poll so this can work in background mode */
+ /* omit window poll so this can work in background mode */
WM_operator_properties_filesel(ot, FOLDERFILE | BLENDERFILE, FILE_BLENDER, FILE_SAVE,
WM_FILESEL_FILEPATH, FILE_DEFAULTDISPLAY);
@@ -3749,8 +3749,8 @@ static void radial_control_set_initial_mouse(RadialControl *rc, const wmEvent *e
d[0] = (1 - rc->initial_value) * WM_RADIAL_CONTROL_DISPLAY_WIDTH + WM_RADIAL_CONTROL_DISPLAY_MIN_SIZE;
break;
case PROP_ANGLE:
- d[0] = WM_RADIAL_CONTROL_DISPLAY_SIZE * cos(rc->initial_value);
- d[1] = WM_RADIAL_CONTROL_DISPLAY_SIZE * sin(rc->initial_value);
+ d[0] = WM_RADIAL_CONTROL_DISPLAY_SIZE * cosf(rc->initial_value);
+ d[1] = WM_RADIAL_CONTROL_DISPLAY_SIZE * sinf(rc->initial_value);
break;
default:
return;
@@ -4251,7 +4251,7 @@ static int radial_control_modal(bContext *C, wmOperator *op, const wmEvent *even
if (snap) new_value = ((int)ceil(new_value * 10.f) * 10.0f) / 100.f;
break;
case PROP_ANGLE:
- new_value = atan2(delta[1], delta[0]) + M_PI + angle_precision;
+ new_value = atan2f(delta[1], delta[0]) + M_PI + angle_precision;
new_value = fmod(new_value, 2.0f * (float)M_PI);
if (new_value < 0.0f)
new_value += 2.0f * (float)M_PI;
@@ -4354,6 +4354,7 @@ static void redraw_timer_window_swap(bContext *C)
{
wmWindow *win = CTX_wm_window(C);
ScrArea *sa;
+ CTX_wm_menu_set(C, NULL);
for (sa = CTX_wm_screen(C)->areabase.first; sa; sa = sa->next)
ED_area_tag_redraw(sa);
@@ -4392,7 +4393,8 @@ static int redraw_timer_exec(bContext *C, wmOperator *op)
}
else if (type == 1) {
wmWindow *win = CTX_wm_window(C);
-
+ CTX_wm_menu_set(C, NULL);
+
ED_region_tag_redraw(ar);
wm_draw_update(C);
@@ -4405,6 +4407,8 @@ static int redraw_timer_exec(bContext *C, wmOperator *op)
ScrArea *sa_back = CTX_wm_area(C);
ARegion *ar_back = CTX_wm_region(C);
+ CTX_wm_menu_set(C, NULL);
+
for (sa = CTX_wm_screen(C)->areabase.first; sa; sa = sa->next) {
ARegion *ar_iter;
CTX_wm_area_set(C, sa);
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 024135e73e9..76add2f9aac 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -98,6 +98,8 @@ typedef struct PlayState {
bool go;
/* waiting for images to load */
bool loading;
+ /* x/y image flip */
+ bool draw_flip[2];
int fstep;
@@ -168,6 +170,15 @@ static void playanim_window_get_size(int *width_r, int *height_r)
GHOST_DisposeRectangle(bounds);
}
+static void playanim_gl_matrix(void)
+{
+ /* unified matrix, note it affects offset for drawing */
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
+ glMatrixMode(GL_MODELVIEW);
+}
+
/* implementation */
static void playanim_event_qual_update(void)
{
@@ -245,7 +256,8 @@ static int pupdate_time(void)
static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep)
{
- float offsx, offsy;
+ float offs_x, offs_y;
+ float span_x, span_y;
if (ibuf == NULL) {
printf("%s: no ibuf for picture '%s'\n", __func__, picture ? picture->name : "<NIL>");
@@ -260,13 +272,17 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf
GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
+ /* size within window */
+ span_x = (ps->zoom * ibuf->x) / (float)ps->win_x;
+ span_y = (ps->zoom * ibuf->y) / (float)ps->win_y;
+
/* offset within window */
- offsx = 0.5f * (((float)ps->win_x - ps->zoom * ibuf->x) / (float)ps->win_x);
- offsy = 0.5f * (((float)ps->win_y - ps->zoom * ibuf->y) / (float)ps->win_y);
+ offs_x = 0.5f * (1.0f - span_x);
+ offs_y = 0.5f * (1.0f - span_y);
- CLAMP(offsx, 0.0f, 1.0f);
- CLAMP(offsy, 0.0f, 1.0f);
- glRasterPos2f(offsx, offsy);
+ CLAMP(offs_x, 0.0f, 1.0f);
+ CLAMP(offs_y, 0.0f, 1.0f);
+ glRasterPos2f(offs_x, offs_y);
glClearColor(0.1, 0.1, 0.1, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
@@ -276,9 +292,15 @@ static void playanim_toscreen(PlayState *ps, PlayAnimPict *picture, struct ImBuf
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- fdrawcheckerboard(offsx, offsy, offsx + (ps->zoom * ibuf->x) / (float)ps->win_x, offsy + (ps->zoom * ibuf->y) / (float)ps->win_y);
+ fdrawcheckerboard(offs_x, offs_y, offs_x + span_x, offs_y + span_y);
}
-
+
+ glRasterPos2f(offs_x + (ps->draw_flip[0] ? span_x : 0.0f),
+ offs_y + (ps->draw_flip[1] ? span_y : 0.0f));
+
+ glPixelZoom(ps->zoom * ps->draw_flip[0] ? -1.0f : 1.0f,
+ ps->zoom * ps->draw_flip[1] ? -1.0f : 1.0f);
+
glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
glDisable(GL_BLEND);
@@ -518,6 +540,14 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
case GHOST_kKeyP:
if (val) ps->pingpong = !ps->pingpong;
break;
+ case GHOST_kKeyF:
+ {
+ if (val) {
+ int axis = (g_WS.qual & WS_QUAL_SHIFT) ? 1 : 0;
+ ps->draw_flip[axis] = !ps->draw_flip[axis];
+ }
+ break;
+ }
case GHOST_kKey1:
case GHOST_kKeyNumpad1:
if (val) swaptime = ps->fstep / 60.0;
@@ -780,13 +810,8 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
glViewport(0, 0, ps->win_x, ps->win_y);
glScissor(0, 0, ps->win_x, ps->win_y);
- /* unified matrix, note it affects offset for drawing */
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
- glMatrixMode(GL_MODELVIEW);
+ playanim_gl_matrix();
- glPixelZoom(ps->zoom, ps->zoom);
ptottime = 0.0;
playanim_toscreen(ps, ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep);
@@ -891,6 +916,8 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
ps.dropped_file[0] = 0;
ps.zoom = 1.0f;
/* resetmap = false */
+ ps.draw_flip[0] = false;
+ ps.draw_flip[1] = false;
ps.fstep = 1;
@@ -1008,11 +1035,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
playanim_window_open("Blender:Anim", start_x, start_y, ibuf->x, ibuf->y);
- /* unified matrix, note it affects offset for drawing */
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
- glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
- glMatrixMode(GL_MODELVIEW);
+ playanim_gl_matrix();
}
GHOST_GetMainDisplayDimensions(g_WS.ghost_system, &maxwinx, &maxwiny);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 20e5b1d8353..46a20d3bf88 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -339,6 +339,19 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win)
}
}
+float wm_window_pixelsize(wmWindow *win)
+{
+ float pixelsize = GHOST_GetNativePixelSize(win->ghostwin);
+
+ switch (U.virtual_pixel) {
+ default:
+ case VIRTUAL_PIXEL_NATIVE:
+ return pixelsize;
+ case VIRTUAL_PIXEL_DOUBLE:
+ return 2.0f * pixelsize;
+ }
+}
+
/* belongs to below */
static void wm_window_add_ghostwindow(wmWindowManager *wm, const char *title, wmWindow *win)
{
@@ -400,7 +413,7 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, const char *title, wm
/* displays with larger native pixels, like Macbook. Used to scale dpi with */
/* needed here, because it's used before it reads userdef */
- U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin);
+ U.pixelsize = wm_window_pixelsize(win);
BKE_userdef_state();
wm_window_swap_buffers(win);
@@ -688,7 +701,7 @@ void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win)
GHOST_ActivateWindowDrawingContext(win->ghostwin);
/* this can change per window */
- U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin);
+ U.pixelsize = wm_window_pixelsize(win);
BKE_userdef_state();
}
}
@@ -1048,7 +1061,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
case GHOST_kEventNativeResolutionChange:
// printf("change, pixel size %f\n", GHOST_GetNativePixelSize(win->ghostwin));
- U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin);
+ U.pixelsize = wm_window_pixelsize(win);
BKE_userdef_state();
WM_event_add_notifier(C, NC_SCREEN | NA_EDITED, NULL);
WM_event_add_notifier(C, NC_WINDOW | NA_EDITED, NULL);
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index a71e0fd9fc9..9c9c79d2f54 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -61,6 +61,8 @@ void wm_window_swap_buffers (wmWindow *win);
void wm_window_set_swap_interval(wmWindow *win, int interval);
bool wm_window_get_swap_interval(wmWindow *win, int *intervalOut);
+float wm_window_pixelsize(wmWindow *win);
+
void wm_get_cursor_position (wmWindow *win, int *x, int *y);
wmWindow *wm_window_copy (bContext *C, wmWindow *winorig);
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 97e7d99c802..649ea1f59c7 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -142,6 +142,7 @@ struct wmWindowManager;
#include "../../intern/dualcon/dualcon.h"
#include "../../intern/elbeem/extern/elbeem.h"
#include "../blender/blenkernel/BKE_modifier.h"
+#include "../blender/blenkernel/BKE_paint.h"
#include "../blender/collada/collada.h"
#include "../blender/compositor/COM_compositor.h"
#include "../blender/editors/include/ED_armature.h"
@@ -168,6 +169,7 @@ struct wmWindowManager;
#include "../blender/editors/include/UI_interface_icons.h"
#include "../blender/editors/include/UI_resources.h"
#include "../blender/editors/include/UI_view2d.h"
+#include "../blender/freestyle/FRS_freestyle.h"
#include "../blender/python/BPY_extern.h"
#include "../blender/render/extern/include/RE_engine.h"
#include "../blender/render/extern/include/RE_pipeline.h"
@@ -229,6 +231,7 @@ void ibuf_sample(struct ImBuf *ibuf, float fx, float fy, float dx, float dy, flo
/* Freestyle */
bool ED_texture_context_check_linestyle(const struct bContext *C) RET_ZERO
+void FRS_free_view_map_cache(void) RET_NONE
/* texture.c */
int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, struct ImagePool *pool, bool scene_color_manage) RET_ZERO
@@ -245,6 +248,9 @@ struct Render *RE_GetRender(const char *name) RET_NULL
float RE_lamp_get_data(struct ShadeInput *shi, struct Object *lamp_obj, float col[4], float lv[3], float *dist, float shadow[4]) RET_ZERO
/* blenkernel */
+bool BKE_paint_proj_mesh_data_check(struct Scene *scene, struct Object *ob, bool *uvs, bool *mat, bool *tex, bool *stencil) RET_ZERO
+
+/* render */
void RE_FreeRenderResult(struct RenderResult *res) RET_NONE
void RE_FreeAllRenderResults(void) RET_NONE
struct RenderResult *RE_MultilayerConvert(void *exrhandle, const char *colorspace, bool predivide, int rectx, int recty) RET_NULL
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 56b017c14dc..20c2448eed3 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -52,6 +52,11 @@ if(WITH_LIBMV)
add_definitions(-DWITH_LIBMV)
endif()
+if(WITH_CYCLES AND WITH_CYCLES_LOGGING)
+ blender_include_dirs(../../intern/cycles/blender)
+ add_definitions(-DWITH_CYCLES_LOGGING)
+endif()
+
if(WITH_CODEC_FFMPEG)
add_definitions(-DWITH_FFMPEG)
endif()
diff --git a/source/creator/creator.c b/source/creator/creator.c
index 768a323a169..12ae5c502e4 100644
--- a/source/creator/creator.c
+++ b/source/creator/creator.c
@@ -149,6 +149,10 @@
# include "libmv-capi.h"
#endif
+#ifdef WITH_CYCLES_LOGGING
+# include "CCL_api.h"
+#endif
+
/* from buildinfo.c */
#ifdef BUILD_DATE
extern char build_date[];
@@ -309,6 +313,9 @@ static int print_help(int UNUSED(argc), const char **UNUSED(argv), void *data)
#ifdef WITH_LIBMV
BLI_argsPrintArgDoc(ba, "--debug-libmv");
#endif
+#ifdef WITH_CYCLES_LOGGING
+ BLI_argsPrintArgDoc(ba, "--debug-cycles");
+#endif
BLI_argsPrintArgDoc(ba, "--debug-memory");
BLI_argsPrintArgDoc(ba, "--debug-jobs");
BLI_argsPrintArgDoc(ba, "--debug-python");
@@ -450,6 +457,15 @@ static int debug_mode_libmv(int UNUSED(argc), const char **UNUSED(argv), void *U
}
#endif
+#ifdef WITH_CYCLES_LOGGING
+static int debug_mode_cycles(int UNUSED(argc), const char **UNUSED(argv),
+ void *UNUSED(data))
+{
+ CCL_start_debug_logging();
+ return 0;
+}
+#endif
+
static int debug_mode_memory(int UNUSED(argc), const char **UNUSED(argv), void *UNUSED(data))
{
MEM_set_memory_debug();
@@ -887,6 +903,8 @@ static int set_verbosity(int argc, const char **argv, void *UNUSED(data))
#ifdef WITH_LIBMV
libmv_setLoggingVerbosity(level);
+#elif defined(WITH_CYCLES_LOGGING)
+ CCL_logging_verbosity_set(level);
#else
(void)level;
#endif
@@ -1419,6 +1437,9 @@ static void setupArguments(bContext *C, bArgs *ba, SYS_SystemHandle *syshandle)
#ifdef WITH_LIBMV
BLI_argsAdd(ba, 1, NULL, "--debug-libmv", "\n\tEnable debug messages from libmv library", debug_mode_libmv, NULL);
#endif
+#ifdef WITH_CYCLES_LOGGING
+ BLI_argsAdd(ba, 1, NULL, "--debug-cycles", "\n\tEnable debug messages from Cycles", debug_mode_cycles, NULL);
+#endif
BLI_argsAdd(ba, 1, NULL, "--debug-memory", "\n\tEnable fully guarded memory allocation and debugging", debug_mode_memory, NULL);
BLI_argsAdd(ba, 1, NULL, "--debug-value", "<value>\n\tSet debug value of <value> on startup\n", set_debug_value, NULL);
@@ -1508,9 +1529,9 @@ int main(
#endif
#ifdef WIN32
- /* FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM (fixed in SP1). Just disable it. */
+ /* FMA3 support in the 2013 CRT is broken on Vista and Windows 7 RTM (fixed in SP1). Just disable it. */
# if defined(_MSC_VER) && _MSC_VER >= 1800 && defined(_M_X64)
- _set_FMA3_enable(0);
+ _set_FMA3_enable(0);
# endif
/* Win32 Unicode Args */
@@ -1583,6 +1604,8 @@ int main(
#ifdef WITH_LIBMV
libmv_initLogging(argv[0]);
+#elif defined(WITH_CYCLES_LOGGING)
+ CCL_init_logging(argv[0]);
#endif
setCallbacks();
diff --git a/source/creator/creator_launch_win.c b/source/creator/creator_launch_win.c
index a7e04b2dafc..03f28cd4034 100644
--- a/source/creator/creator_launch_win.c
+++ b/source/creator/creator_launch_win.c
@@ -58,9 +58,14 @@ int main(int argc, const char **UNUSED(argv_c))
wcsncpy(command, BLENDER_BINARY, len - 1);
len -= wcslen(BLENDER_BINARY);
for (i = 1; i < argc; ++i) {
+ size_t argument_len = wcslen(argv_16[i]);
wcsncat(command, L" \"", len - 2);
wcsncat(command, argv_16[i], len - 3);
- len -= wcslen(argv_16[i]) + 1;
+ len -= argument_len + 1;
+ if (argv_16[i][argument_len - 1] == '\\') {
+ wcsncat(command, L"\\", len - 1);
+ len--;
+ }
wcsncat(command, L"\"", len - 1);
}
diff --git a/source/creator/osx_locals.map b/source/creator/osx_locals.map
index a1d7e7fed57..8405be74ab7 100644
--- a/source/creator/osx_locals.map
+++ b/source/creator/osx_locals.map
@@ -2,4 +2,7 @@
## (aka visibility=hidden) and will not be global in the output file
*boost*
*__ZNSt6vector*
+*llvm*
+*LLVM*
+*OSL*
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index a7c98eb9dc1..2a7e631637e 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -67,6 +67,7 @@
extern "C" {
+ #include "DNA_object_types.h"
#include "DNA_view3d_types.h"
#include "DNA_screen_types.h"
#include "DNA_userdef_types.h"
@@ -282,6 +283,10 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
bool mouse_state = startscene->gm.flag & GAME_SHOW_MOUSE;
bool restrictAnimFPS = startscene->gm.flag & GAME_RESTRICT_ANIM_UPDATES;
+ short drawtype = v3d->drawtype;
+
+ /* we do not support material mode in game engine, force change to texture mode */
+ if (drawtype == OB_MATERIAL) drawtype = OB_TEXTURE;
if (animation_record) usefixed= false; /* override since you don't want to run full-speed for sim recording */
// create the canvas and rasterizer
@@ -371,7 +376,7 @@ extern "C" void StartKetsjiShell(struct bContext *C, struct ARegion *ar, rcti *c
camzoom = 2.0;
}
- rasterizer->SetDrawingMode(v3d->drawtype);
+ rasterizer->SetDrawingMode(drawtype);
ketsjiengine->SetCameraZoom(camzoom);
// if we got an exitcode 3 (KX_EXIT_REQUEST_START_OTHER_GAME) load a different file
diff --git a/source/gameengine/Converter/BL_ArmatureObject.cpp b/source/gameengine/Converter/BL_ArmatureObject.cpp
index 8d73e591113..e01130a8970 100644
--- a/source/gameengine/Converter/BL_ArmatureObject.cpp
+++ b/source/gameengine/Converter/BL_ArmatureObject.cpp
@@ -101,7 +101,7 @@ static void game_copy_pose(bPose **dst, bPose *src, int copy_constraint)
out->chanhash = NULL;
out->agroups.first= out->agroups.last= NULL;
out->ikdata = NULL;
- out->ikparam = MEM_dupallocN(src->ikparam);
+ out->ikparam = MEM_dupallocN(src->ikparam);
out->flag |= POSE_GAME_ENGINE;
BLI_duplicatelist(&out->chanbase, &src->chanbase);
diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
index 14772cda113..f76580cd44d 100644
--- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
+++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp
@@ -1734,18 +1734,17 @@ void KX_KetsjiEngine::AddScheduledScenes()
bool KX_KetsjiEngine::ReplaceScene(const STR_String& oldscene,const STR_String& newscene)
{
- // Don't allow replacement if the new scene doesn't exists.
- // Allows smarter game design (used to have no check here).
- // Note that it creates a small backward compatbility issue
- // for a game that did a replace followed by a lib load with the
- // new scene in the lib => it won't work anymore, the lib
- // must be loaded before doing the replace.
- if (m_sceneconverter->GetBlenderSceneForName(newscene) != NULL)
- {
- m_replace_scenes.push_back(std::make_pair(oldscene,newscene));
- return true;
- }
- return false;
+ // Don't allow replacement if the new scene doesn't exists.
+ // Allows smarter game design (used to have no check here).
+ // Note that it creates a small backward compatbility issue
+ // for a game that did a replace followed by a lib load with the
+ // new scene in the lib => it won't work anymore, the lib
+ // must be loaded before doing the replace.
+ if (m_sceneconverter->GetBlenderSceneForName(newscene) != NULL) {
+ m_replace_scenes.push_back(std::make_pair(oldscene,newscene));
+ return true;
+ }
+ return false;
}
// replace scene is not the same as removing and adding because the
@@ -1767,21 +1766,20 @@ void KX_KetsjiEngine::ReplaceScheduledScenes()
int i=0;
/* Scenes are not supposed to be included twice... I think */
KX_SceneList::iterator sceneit;
- for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++)
- {
- KX_Scene* scene = *sceneit;
- if (scene->GetName() == oldscenename)
- {
- // avoid crash if the new scene doesn't exist, just do nothing
- Scene *blScene = m_sceneconverter->GetBlenderSceneForName(newscenename);
- if (blScene) {
- m_sceneconverter->RemoveScene(scene);
- KX_Scene* tmpscene = CreateScene(blScene);
- m_scenes[i]=tmpscene;
- PostProcessScene(tmpscene);
- } else {
- printf("warning: scene %s could not be found, not replaced!\n",newscenename.ReadPtr());
- }
+ for (sceneit = m_scenes.begin();sceneit != m_scenes.end() ; sceneit++) {
+ KX_Scene* scene = *sceneit;
+ if (scene->GetName() == oldscenename) {
+ // avoid crash if the new scene doesn't exist, just do nothing
+ Scene *blScene = m_sceneconverter->GetBlenderSceneForName(newscenename);
+ if (blScene) {
+ m_sceneconverter->RemoveScene(scene);
+ KX_Scene* tmpscene = CreateScene(blScene);
+ m_scenes[i]=tmpscene;
+ PostProcessScene(tmpscene);
+ }
+ else {
+ printf("warning: scene %s could not be found, not replaced!\n",newscenename.ReadPtr());
+ }
}
i++;
}
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 625bbee2c8e..d0eab9de1c1 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -1577,7 +1577,7 @@ void KX_Scene::AddAnimatedObject(CValue* gameobj)
static void update_anim_thread_func(TaskPool *pool, void *taskdata, int UNUSED(threadid))
{
- KX_GameObject *gameobj, *child;
+ KX_GameObject *gameobj, *child, *parent;
CListValue *children;
bool needs_update;
double curtime = *(double*)BLI_task_pool_userdata(pool);
@@ -1621,8 +1621,11 @@ static void update_anim_thread_func(TaskPool *pool, void *taskdata, int UNUSED(t
if (needs_update) {
gameobj->UpdateActionManager(curtime);
children = gameobj->GetChildren();
+ parent = gameobj->GetParent();
- if (!gameobj->GetParent() && gameobj->GetDeformer())
+ // Only do deformers here if they are not parented to an armature, otherwise the armature will
+ // handle updating its children
+ if (gameobj->GetDeformer() && (!parent || (parent && parent->GetGameObjectType() != SCA_IObject::OBJ_ARMATURE)))
gameobj->GetDeformer()->Update();
for (int j=0; j<children->GetCount(); ++j) {
diff --git a/tests/gtests/blenlib/BLI_polyfill2d_test.cc b/tests/gtests/blenlib/BLI_polyfill2d_test.cc
new file mode 100644
index 00000000000..785274757aa
--- /dev/null
+++ b/tests/gtests/blenlib/BLI_polyfill2d_test.cc
@@ -0,0 +1,492 @@
+/* Apache License, Version 2.0 */
+
+#include "testing/testing.h"
+
+/* Use to write out OBJ files, handy for checking output */
+// #define USE_OBJ_PREVIEW
+
+/* test every possible offset and reverse */
+#define USE_COMBINATIONS_ALL
+
+extern "C" {
+#include "BLI_array.h"
+#include "BLI_polyfill2d.h"
+#include "BLI_math.h"
+#include "BLI_edgehash.h"
+#include "MEM_guardedalloc.h"
+
+#ifdef USE_OBJ_PREVIEW
+# include "BLI_string.h"
+#endif
+}
+
+static void polyfill_to_obj(
+ const char *id,
+ const float poly[][2], const unsigned int poly_tot,
+ const unsigned int tris[][3], const unsigned int tris_tot);
+
+/* -------------------------------------------------------------------- */
+/* test utility functions */
+
+#define TRI_ERROR_VALUE (unsigned int)-1
+
+static void test_valid_polyfill_prepare(unsigned int tris[][3], unsigned int tris_tot)
+{
+ unsigned int i;
+ for (i = 0; i < tris_tot; i++) {
+ unsigned int j;
+ for (j = 0; j < 3; j++) {
+ tris[i][j] = TRI_ERROR_VALUE;
+ }
+ }
+}
+
+/**
+ * Basic check for face index values:
+ *
+ * - no duplicates.
+ * - all tris set.
+ * - all verts used at least once.
+ */
+static void test_polyfill_simple(
+ const float poly[][2], const unsigned int poly_tot,
+ const unsigned int tris[][3], const unsigned int tris_tot)
+{
+ unsigned int i;
+ int *tot_used = (int *)MEM_callocN(poly_tot * sizeof(int), __func__);
+ for (i = 0; i < tris_tot; i++) {
+ unsigned int j;
+ for (j = 0; j < 3; j++) {
+ EXPECT_NE(TRI_ERROR_VALUE, tris[i][j]);
+ tot_used[tris[i][j]] += 1;
+ }
+ EXPECT_NE(tris[i][0], tris[i][1]);
+ EXPECT_NE(tris[i][1], tris[i][2]);
+ EXPECT_NE(tris[i][2], tris[i][0]);
+ }
+ for (i = 0; i < poly_tot; i++) {
+ EXPECT_NE(0, tot_used[i]);
+ }
+ MEM_freeN(tot_used);
+}
+
+static void test_polyfill_topology(
+ const float poly[][2], const unsigned int poly_tot,
+ const unsigned int tris[][3], const unsigned int tris_tot)
+{
+ EdgeHash *edgehash = BLI_edgehash_new(__func__);
+ EdgeHashIterator *ehi;
+ unsigned int i;
+ for (i = 0; i < tris_tot; i++) {
+ unsigned int j;
+ for (j = 0; j < 3; j++) {
+ const unsigned int v1 = tris[i][j];
+ const unsigned int v2 = tris[i][(j + 1) % 3];
+ void **p = BLI_edgehash_lookup_p(edgehash, v1, v2);
+ if (p) {
+ *p = (void *)((intptr_t)*p + (intptr_t)1);
+ }
+ else {
+ BLI_edgehash_insert(edgehash, v1, v2, (void *)(intptr_t)1);
+ }
+ }
+ }
+ EXPECT_EQ(poly_tot + (poly_tot - 3), BLI_edgehash_size(edgehash));
+
+ for (i = 0; i < poly_tot; i++) {
+ const unsigned int v1 = i;
+ const unsigned int v2 = (i + 1) % poly_tot;
+ void **p = BLI_edgehash_lookup_p(edgehash, v1, v2);
+ EXPECT_EQ(1, (void *)p != NULL);
+ EXPECT_EQ(1, (intptr_t)*p);
+ }
+
+ for (ehi = BLI_edgehashIterator_new(edgehash), i = 0;
+ BLI_edgehashIterator_isDone(ehi) == false;
+ BLI_edgehashIterator_step(ehi), i++)
+ {
+ void **p = BLI_edgehashIterator_getValue_p(ehi);
+ EXPECT_EQ(true, ELEM((intptr_t)*p, 1, 2));
+ }
+
+ BLI_edgehash_free(edgehash, NULL);
+}
+
+/**
+ * Check all faces are flipped the same way
+ */
+static void test_polyfill_winding(
+ const float poly[][2], const unsigned int poly_tot,
+ const unsigned int tris[][3], const unsigned int tris_tot)
+{
+ unsigned int i;
+ unsigned int count[2] = {0, 0};
+ for (i = 0; i < tris_tot; i++) {
+ float winding_test = cross_tri_v2(poly[tris[i][0]], poly[tris[i][1]], poly[tris[i][2]]);
+ if (fabsf(winding_test) > FLT_EPSILON) {
+ count[winding_test < 0.0f] += 1;
+ }
+ }
+ EXPECT_EQ(true, ELEM(0, count[0], count[1]));
+}
+
+/**
+ * Check the accumulated triangle area is close to the original area.
+ */
+static void test_polyfill_area(
+ const float poly[][2], const unsigned int poly_tot,
+ const unsigned int tris[][3], const unsigned int tris_tot)
+{
+ unsigned int i;
+ const float area_tot = area_poly_v2(poly, poly_tot);
+ float area_tot_tris = 0.0f;
+ const float eps_abs = 0.00001f;
+ const float eps = area_tot > 1.0f ? (area_tot * eps_abs) : eps_abs;
+ for (i = 0; i < tris_tot; i++) {
+ area_tot_tris += area_tri_v2(poly[tris[i][0]], poly[tris[i][1]], poly[tris[i][2]]);
+ }
+ EXPECT_NEAR(area_tot, area_tot_tris, eps);
+}
+
+
+/* -------------------------------------------------------------------- */
+/* Macro and helpers to manage checking */
+/**
+ * Main template for polyfill testing.
+ */
+static void test_polyfill_template_check(
+ const char *id, bool is_degenerate,
+ const float poly[][2], const unsigned int poly_tot,
+ const unsigned int tris[][3], const unsigned int tris_tot)
+{
+ test_polyfill_simple(poly, poly_tot, tris, tris_tot);
+ test_polyfill_topology(poly, poly_tot, tris, tris_tot);
+ if (!is_degenerate) {
+ test_polyfill_winding(poly, poly_tot, tris, tris_tot);
+
+ test_polyfill_area(poly, poly_tot, tris, tris_tot);
+ }
+ polyfill_to_obj(id, poly, poly_tot, tris, tris_tot);
+}
+
+static void test_polyfill_template(
+ const char *id, bool is_degenerate,
+ const float poly[][2], const unsigned int poly_tot,
+ unsigned int tris[][3], const unsigned int tris_tot)
+{
+ test_valid_polyfill_prepare(tris, tris_tot);
+ BLI_polyfill_calc(poly, poly_tot, 0, tris);
+
+ /* check all went well */
+ test_polyfill_template_check(id, is_degenerate, poly, poly_tot, tris, tris_tot);
+}
+
+#ifdef USE_COMBINATIONS_ALL
+static void test_polyfill_template_main(
+ const char *id, bool is_degenerate,
+ const float poly[][2], const unsigned int poly_tot,
+ unsigned int tris[][3], const unsigned int tris_tot)
+{
+ /* overkill? - try at _every_ offset & reverse */
+ unsigned int poly_reverse;
+ float (*poly_copy)[2] = (float (*)[2])MEM_mallocN(sizeof(float[2]) * poly_tot, id);
+ float tmp[2];
+
+ memcpy(poly_copy, poly, sizeof(float[2]) * poly_tot);
+
+ for (poly_reverse = 0; poly_reverse < 2; poly_reverse++) {
+ unsigned int poly_cycle;
+
+ if (poly_reverse) {
+ BLI_array_reverse(poly_copy, poly_tot);
+ }
+
+ for (poly_cycle = 0; poly_cycle < poly_tot; poly_cycle++) {
+ // printf("polytest %s ofs=%d, reverse=%d\n", id, poly_cycle, poly_reverse);
+ test_polyfill_template(id, is_degenerate, poly, poly_tot, tris, tris_tot);
+
+ /* cycle */
+ copy_v2_v2(tmp, poly_copy[0]);
+ memmove(&poly_copy[0], &poly_copy[1], (poly_tot - 1) * sizeof(float[2]));
+ copy_v2_v2(poly_copy[poly_tot - 1], tmp);
+ }
+ }
+
+ MEM_freeN(poly_copy);
+}
+#else /* USE_COMBINATIONS_ALL */
+static void test_polyfill_template_main(
+ const char *id, bool is_degenerate,
+ const float poly[][2], const unsigned int poly_tot,
+ unsigned int tris[][3], const unsigned int tris_tot)
+{
+ test_polyfill_template(id, is_degenerate, poly, poly_tot, tris, tris_tot);
+}
+#endif /* USE_COMBINATIONS_ALL */
+
+#define TEST_POLYFILL_TEMPLATE_STATIC(poly, is_degenerate) \
+{ \
+ unsigned int tris[POLY_TRI_COUNT(ARRAY_SIZE(poly))][3]; \
+ const unsigned int poly_tot = ARRAY_SIZE(poly); \
+ const unsigned int tris_tot = ARRAY_SIZE(tris); \
+ const char *id = typeid(*this).name(); \
+ \
+ test_polyfill_template_main(id, is_degenerate, poly, poly_tot, tris, tris_tot); \
+} (void)0
+
+/* -------------------------------------------------------------------- */
+/* visualisation functions (not needed for testing) */
+
+#ifdef USE_OBJ_PREVIEW
+static void polyfill_to_obj(
+ const char *id,
+ const float poly[][2], const unsigned int poly_tot,
+ const unsigned int tris[][3], const unsigned int tris_tot)
+{
+ char path[1024];
+ FILE *f;
+ unsigned int i;
+
+ BLI_snprintf(path, sizeof(path), "%s.obj", id);
+
+ f = fopen(path, "w");
+ if (!f) {
+ return;
+ }
+
+ for (i = 0; i < poly_tot; i++) {
+ fprintf(f, "v %f %f 0.0\n", UNPACK2(poly[i]));
+ }
+
+ for (i = 0; i < tris_tot; i++) {
+ fprintf(f, "f %u %u %u\n", UNPACK3_EX(1 +, tris[i], ));
+ }
+
+ fclose(f);
+}
+#else
+static void polyfill_to_obj(
+ const char *id,
+ const float poly[][2], const unsigned int poly_tot,
+ const unsigned int tris[][3], const unsigned int tris_tot)
+{
+ (void)id;
+ (void)poly, (void)poly_tot;
+ (void)tris, (void)tris_tot;
+}
+#endif /* USE_OBJ_PREVIEW */
+
+
+/* -------------------------------------------------------------------- */
+/* tests */
+
+#define POLY_TRI_COUNT(len) ((len) - 2)
+
+
+/* A counterclockwise triangle */
+TEST(polyfill2d, TriangleCCW)
+{
+ const float poly[][2] = {{0, 0}, {0, 1}, {1, 0}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* A counterclockwise square */
+TEST(polyfill2d, SquareCCW)
+{
+ const float poly[][2] = {{0, 0}, {0, 1}, {1, 1}, {1, 0}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* A clockwise square */
+TEST(polyfill2d, SquareCW)
+{
+ const float poly[][2] = {{0, 0}, {1, 0}, {1, 1}, {0, 1}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Starfleet insigna */
+TEST(polyfill2d, Starfleet)
+{
+ const float poly[][2] = {{0, 0}, {0.6f, 0.4f}, {1, 0}, {0.5f, 1}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Starfleet insigna with repeated point */
+TEST(polyfill2d, StarfleetDegenerate)
+{
+ const float poly[][2] = {{0, 0}, {0.6f, 0.4f}, {0.6f, 0.4f}, {1, 0}, {0.5f, 1}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Three collinear points */
+TEST(polyfill2d, 3Colinear)
+{
+ const float poly[][2] = {{0, 0}, {1, 0}, {2, 0}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Four collinear points */
+TEST(polyfill2d, 4Colinear)
+{
+ const float poly[][2] = {{0, 0}, {1, 0}, {2, 0}, {3, 0}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Non-consecutive collinear points */
+TEST(polyfill2d, UnorderedColinear)
+{
+ const float poly[][2] = {{0, 0}, {1, 1}, {2, 0}, {3, 1}, {4, 0}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Plus shape */
+TEST(polyfill2d, PlusShape)
+{
+ const float poly[][2] = {
+ {1, 0}, {2, 0}, {2, 1}, {3, 1}, {3, 2}, {2, 2}, {2, 3}, {1, 3}, {1, 2}, {0, 2}, {0, 1}, {1, 1}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Star shape */
+TEST(polyfill2d, StarShape)
+{
+ const float poly[][2] = {
+ {4, 0}, {5, 3}, {8, 4}, {5, 5}, {4, 8}, {3, 5}, {0, 4}, {3, 3}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* U shape */
+TEST(polyfill2d, UShape)
+{
+ const float poly[][2] = {
+ {1, 0}, {2, 0}, {3, 1}, {3, 3}, {2, 3}, {2, 1}, {1, 1}, {1, 3}, {0, 3}, {0, 1}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Spiral */
+TEST(polyfill2d, Spiral)
+{
+ const float poly[][2] = {
+ {1, 0}, {4, 0}, {5, 1}, {5, 4}, {4, 5}, {1, 5}, {0, 4}, {0, 3},
+ {1, 2}, {2, 2}, {3, 3}, {1, 3}, {1, 4}, {4, 4}, {4, 1}, {0, 1}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Test case from http:# www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml */
+TEST(polyfill2d, TestFlipCode)
+{
+ const float poly[][2] = {
+ {0, 6}, {0, 0}, {3, 0}, {4, 1}, {6, 1}, {8, 0}, {12, 0}, {13, 2},
+ {8, 2}, {8, 4}, {11, 4}, {11, 6}, {6, 6}, {4, 3}, {2, 6}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Self-intersection */
+TEST(polyfill2d, SelfIntersect)
+{
+ const float poly[][2] = {{0, 0}, {1, 1}, {2, -1}, {3, 1}, {4, 0}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, true);
+}
+
+/* Self-touching */
+TEST(polyfill2d, SelfTouch)
+{
+ const float poly[][2] = {
+ {0, 0}, {4, 0}, {4, 4}, {2, 4}, {2, 3}, {3, 3}, {3, 1}, {1, 1}, {1, 3}, {2, 3}, {2, 4}, {0, 4}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Self-overlapping */
+TEST(polyfill2d, SelfOverlap)
+{
+ const float poly[][2] = {
+ {0, 0}, {4, 0}, {4, 4}, {1, 4}, {1, 3}, {3, 3}, {3, 1}, {1, 1}, {1, 3}, {3, 3}, {3, 4}, {0, 4}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, true);
+}
+
+/* Test case from http:# www.davdata.nl/math/polygons.html */
+TEST(polyfill2d, TestDavData)
+{
+ const float poly[][2] = {
+ {190, 480}, {140, 180}, {310, 100}, {330, 390}, {290, 390}, {280, 260}, {220, 260}, {220, 430}, {370, 430},
+ {350, 30}, {50, 30}, {160, 560}, {730, 510}, {710, 20}, {410, 30}, {470, 440}, {640, 410}, {630, 140},
+ {590, 140}, {580, 360}, {510, 370}, {510, 60}, {650, 70}, {660, 450}, {190, 480}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Issue 815, http:# code.google.com/p/libgdx/issues/detail?id=815 */
+TEST(polyfill2d, Issue815)
+{
+ const float poly[][2] = {
+ {-2.0f, 0.0f}, {-2.0f, 0.5f}, {0.0f, 1.0f}, {0.5f, 2.875f},
+ {1.0f, 0.5f}, {1.5f, 1.0f}, {2.0f, 1.0f}, {2.0f, 0.0f}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Issue 207, comment #1, http:# code.google.com/p/libgdx/issues/detail?id=207#c1 */
+TEST(polyfill2d, Issue207_1)
+{
+ const float poly[][2] = {
+ {72.42465f, 197.07095f}, {78.485535f, 189.92776f}, {86.12059f, 180.92929f}, {99.68253f, 164.94557f},
+ {105.24325f, 165.79604f}, {107.21862f, 166.09814f}, {112.41958f, 162.78253f}, {113.73238f, 161.94562f},
+ {123.29477f, 167.93805f}, {126.70667f, 170.07617f}, {73.22717f, 199.51062f}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, true);
+}
+
+/* Issue 207, comment #11, http:# code.google.com/p/libgdx/issues/detail?id=207#c11 */
+/* Also on issue 1081, http:# code.google.com/p/libgdx/issues/detail?id=1081 */
+TEST(polyfill2d, Issue207_11)
+{
+ const float poly[][2] = {
+ {2400.0f, 480.0f}, {2400.0f, 176.0f}, {1920.0f, 480.0f}, {1920.0459f, 484.22314f},
+ {1920.1797f, 487.91016f}, {1920.3955f, 491.0874f}, {1920.6875f, 493.78125f}, {1921.0498f, 496.01807f},
+ {1921.4766f, 497.82422f}, {1921.9619f, 499.22607f}, {1922.5f, 500.25f}, {1923.085f, 500.92236f},
+ {1923.7109f, 501.26953f}, {1924.3721f, 501.31787f}, {1925.0625f, 501.09375f}, {1925.7764f, 500.62354f},
+ {1926.5078f, 499.9336f}, {1927.251f, 499.0503f}, {1928.0f, 498.0f}, {1928.749f, 496.80908f},
+ {1929.4922f, 495.5039f}, {1930.2236f, 494.11084f}, {1930.9375f, 492.65625f}, {1931.6279f, 491.1665f},
+ {1932.2891f, 489.66797f}, {1932.915f, 488.187f}, {1933.5f, 486.75f}, {1934.0381f, 485.3833f},
+ {1934.5234f, 484.11328f}, {1934.9502f, 482.9663f}, {1935.3125f, 481.96875f}, {1935.6045f, 481.14697f},
+ {1935.8203f, 480.52734f}, {1935.9541f, 480.13623f}, {1936.0f, 480.0f}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Issue 1407, http:# code.google.com/p/libgdx/issues/detail?id=1407 */
+TEST(polyfill2d, Issue1407)
+{
+ const float poly[][2] = {
+ {3.914329f, 1.9008259f}, {4.414321f, 1.903619f}, {4.8973203f, 1.9063174f}, {5.4979978f, 1.9096732f}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Issue 1407, http:# code.google.com/p/libgdx/issues/detail?id=1407, */
+/* with an additional point to show what is happening. */
+TEST(polyfill2d, Issue1407_pt)
+{
+ const float poly[][2] = {
+ {3.914329f, 1.9008259f}, {4.414321f, 1.903619f}, {4.8973203f, 1.9063174f}, {5.4979978f, 1.9096732f}, {4, 4}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Simplified from Blender bug T40777 */
+TEST(polyfill2d, IssueT40777_colinear)
+{
+ const float poly[][2] = {
+ {0.7, 0.37}, {0.7, 0}, {0.76, 0}, {0.76, 0.4}, {0.83, 0.4}, {0.83, 0}, {0.88, 0}, {0.88, 0.4},
+ {0.94, 0.4}, {0.94, 0}, {1, 0}, {1, 0.4}, {0.03, 0.62}, {0.03, 0.89}, {0.59, 0.89}, {0.03, 1},
+ {0, 1}, {0, 0}, {0.03, 0}, {0.03, 0.37}};
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
+
+/* Blender bug T41986 */
+TEST(polyfill2d, IssueT41986_axis_align)
+{
+ const float poly[][2] = {
+ {-0.25, -0.07}, {-0.25, 0.27}, {-1.19, 0.14}, {-0.06, 0.73}, {0.17, 1.25}, {-0.25, 1.07},
+ {-0.38, 1.02}, {-0.25, 0.94}, {-0.40, 0.90}, {-0.41, 0.86}, {-0.34, 0.83}, {-0.25, 0.82},
+ {-0.66, 0.73}, {-0.56, 1.09}, {-0.25, 1.10}, {0.00, 1.31}, {-0.03, 1.47}, {-0.25, 1.53},
+ {0.12, 1.62}, {0.36, 1.07}, {0.12, 0.67}, {0.29, 0.57}, {0.44, 0.45}, {0.57, 0.29},
+ {0.66, 0.12}, {0.68, 0.06}, {0.57, -0.36}, {-0.25, -0.37}, {0.49, -0.74}, {-0.59, -1.21},
+ {-0.25, -0.15}, {-0.46, -0.52}, {-1.08, -0.83}, {-1.45, -0.33}, {-1.25, -0.04}};
+
+ TEST_POLYFILL_TEMPLATE_STATIC(poly, false);
+}
diff --git a/tests/gtests/blenlib/BLI_stack_test.cc b/tests/gtests/blenlib/BLI_stack_test.cc
index c4884cb8940..08701356816 100644
--- a/tests/gtests/blenlib/BLI_stack_test.cc
+++ b/tests/gtests/blenlib/BLI_stack_test.cc
@@ -88,6 +88,29 @@ TEST(stack, String)
BLI_stack_free(stack);
}
+TEST(stack, Peek)
+{
+ const int tot = SIZE;
+ int i;
+
+ BLI_Stack *stack;
+ const short in[] = {1, 10, 100, 1000};
+
+ stack = BLI_stack_new(sizeof(*in), __func__);
+
+ for (i = 0; i < tot; i++) {
+ BLI_stack_push(stack, &in[i % ARRAY_SIZE(in)]);
+ }
+
+ for (i = tot - 1; i >= 0; i--, BLI_stack_discard(stack)) {
+ short *ret = (short *)BLI_stack_peek(stack);
+ EXPECT_EQ(*ret, in[i % ARRAY_SIZE(in)]);
+ }
+
+ EXPECT_EQ(BLI_stack_is_empty(stack), true);
+}
+
+
TEST(stack, Reuse)
{
const int sizes[] = {3, 11, 81, 400, 999, 12, 1, 9721, 7, 99, 5, 0};
diff --git a/tests/gtests/blenlib/CMakeLists.txt b/tests/gtests/blenlib/CMakeLists.txt
index 07b89a9042e..c949c1e1f5c 100644
--- a/tests/gtests/blenlib/CMakeLists.txt
+++ b/tests/gtests/blenlib/CMakeLists.txt
@@ -40,4 +40,5 @@ BLENDER_TEST(BLI_math_color "bf_blenlib")
BLENDER_TEST(BLI_math_geom "bf_blenlib")
BLENDER_TEST(BLI_string "bf_blenlib")
BLENDER_TEST(BLI_path_util "bf_blenlib;extern_wcwidth;${ZLIB_LIBRARIES}")
+BLENDER_TEST(BLI_polyfill2d "bf_blenlib")
BLENDER_TEST(BLI_listbase "bf_blenlib")
diff --git a/tests/python/bl_mesh_modifiers.py b/tests/python/bl_mesh_modifiers.py
index 1c05eaafa0d..2db38895f9b 100644
--- a/tests/python/bl_mesh_modifiers.py
+++ b/tests/python/bl_mesh_modifiers.py
@@ -851,7 +851,7 @@ if __name__ == "__main__":
import traceback
traceback.print_exc()
- import sys
+ # import sys
# sys.exit(1) # comment to debug
else:
diff --git a/tests/python/rna_array.py b/tests/python/rna_array.py
index d3014868bcb..f9777a5b438 100644
--- a/tests/python/rna_array.py
+++ b/tests/python/rna_array.py
@@ -266,7 +266,7 @@ def prop_to_list(prop):
ret= []
for x in prop:
- if type(x) not in (bool, int, float):
+ if type(x) not in {bool, int, float}:
ret.append(prop_to_list(x))
else:
ret.append(x)